home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / Entertainment / MacMud / Mud 4.0 / lang.y < prev    next >
Encoding:
Lex Description  |  1993-03-24  |  73.6 KB  |  2,648 lines  |  [TEXT/????]

  1. %{
  2. # line 3 "prelang.y"
  3. /* The above line is to give proper line number references. Please mail me
  4.  * if your compiler complains about it.
  5.  */
  6. /*
  7.  * This is the grammar definition of LPC. The token table is built
  8.  * automatically by make_func. The lang.y is constructed from this file,
  9.  * the generated token list and post_lang.y. The reason of this is that there
  10.  * is no #include-statment that yacc recognizes.
  11.  */
  12. #include <string.h>
  13. #include <stdio.h>
  14. #include <memory.h>
  15. #if defined(sun)
  16. #include <alloca.h>
  17. #endif
  18.  
  19. #include "lint.h"
  20. #include "interpret.h"
  21. #include "object.h"
  22. #include "exec.h"
  23. #include "config.h"
  24. #include "instrs.h"
  25. #include "incralloc.h"
  26. #include "switch.h"
  27. #include "rc.h"
  28.  
  29. #if defined(__GNUC__) && !defined(lint) && !defined(DEBUG)
  30. #define INLINE inline
  31. #else
  32. #define INLINE
  33. #endif
  34.  
  35. #define YYMAXDEPTH    600
  36.  
  37. /* NUMPAREAS areas are saved with the program code after compilation.
  38.  */
  39. #define A_PROGRAM        0
  40. #define A_FUNCTIONS        1
  41. #define A_STRINGS        2
  42. #define A_VARIABLES        3
  43. #define A_LINENUMBERS        4
  44. #define A_INHERITS        5
  45. #define A_ARGUMENT_TYPES    6
  46. #define A_ARGUMENT_INDEX    7
  47. #define NUMPAREAS        8
  48. #define A_CASE_NUMBERS        8
  49. #define A_CASE_STRINGS        9
  50. #define A_CASE_LABELS           10
  51. #define NUMAREAS           11
  52.  
  53. #define BREAK_ON_STACK        0x40000
  54. #define BREAK_FROM_CASE        0x80000
  55.  
  56. /* make shure that this struct has a size that is a power of two */
  57. struct case_heap_entry { int key; short addr; short line; };
  58. #define CASE_HEAP_ENTRY_ALIGN(offset) offset &= -sizeof(struct case_heap_entry)
  59.  
  60. static struct mem_block mem_block[NUMAREAS];
  61.  
  62. /*
  63.  * Some good macros to have.
  64.  */
  65.  
  66. #define BASIC_TYPE(e,t) ((e) == TYPE_ANY ||\
  67.              (e) == (t) ||\
  68.              (t) == TYPE_ANY)
  69.  
  70. #define TYPE(e,t) (BASIC_TYPE((e) & TYPE_MOD_MASK, (t) & TYPE_MOD_MASK) ||\
  71.            (((e) & TYPE_MOD_POINTER) && ((t) & TYPE_MOD_POINTER) &&\
  72.             BASIC_TYPE((e) & (TYPE_MOD_MASK & ~TYPE_MOD_POINTER),\
  73.                    (t) & (TYPE_MOD_MASK & ~TYPE_MOD_POINTER))))
  74.  
  75. #define FUNCTION(n) ((struct function *)mem_block[A_FUNCTIONS].block + (n))
  76. #define VARIABLE(n) ((struct variable *)mem_block[A_VARIABLES].block + (n))
  77.  
  78. #define align(x) (((x) + 3) & ~3)
  79.  
  80. /*
  81.  * If the type of the function is given, then strict types are
  82.  * checked and required.
  83.  */
  84. static int exact_types;
  85. extern int pragma_strict_types;    /* Maintained by lex.c */
  86. extern int pragma_save_types;    /* Also maintained by lex.c */
  87. int approved_object;        /* How I hate all these global variables */
  88.  
  89. extern int total_num_prog_blocks, total_prog_block_size;
  90.  
  91. extern int num_parse_error;
  92. extern int d_flag;
  93. static int heart_beat;        /* Number of the heart beat function */
  94.  
  95. static int current_break_address;
  96. static int current_continue_address;
  97. static int current_case_number_heap;
  98. static int current_case_string_heap;
  99. #define SOME_NUMERIC_CASE_LABELS 0x40000
  100. #define NO_STRING_CASE_LABELS    0x80000
  101. static int zero_case_label;
  102. static int current_type;
  103.  
  104. static int last_push_indexed;
  105. static int last_push_local;
  106. static int last_push_identifier;
  107.  
  108. /*
  109.  * There is always function starting at address 0, which will execute
  110.  * the initialization code. This code is spread all over the program,
  111.  * with jumps to next initializer. The next variable keeps track of
  112.  * the previous jump. After the last initializer, the jump will be changed
  113.  * into a return(0) statement instead.
  114.  *
  115.  * A function named '__INIT' will be defined, which will contain the
  116.  * initialization code. If there was no initialization code, then the
  117.  * function will not be defined. That is the usage of the
  118.  * first_last_initializer_end variable.
  119.  *
  120.  * When inheriting from another object, a call will automatically be made
  121.  * to call __INIT in that code from the current __INIT.
  122.  */
  123. static int last_initializer_end;
  124. static int first_last_initializer_end;
  125.  
  126. static struct program NULL_program; /* marion - clean neat empty struct */
  127.  
  128. void epilog();
  129. static int check_declared PROT((char *str));
  130. static void prolog();
  131. static char *get_two_types PROT((int type1, int type2));
  132. void free_all_local_names(),
  133.     add_local_name PROT((char *, int)), smart_log PROT((char *, int, char *));
  134. extern int yylex();
  135. extern char *findstring PROT((char *));
  136. static int verify_declared PROT((char *));
  137. static void copy_variables();
  138. static int copy_functions PROT((struct program *, int type));
  139. void type_error PROT((char *, int));
  140.  
  141. char *xalloc(), *string_copy();
  142.  
  143. extern int current_line;
  144. /*
  145.  * 'inherit_file' is used as a flag. If it is set to a string
  146.  * after yyparse(), this string should be loaded as an object,
  147.  * and the original object must be loaded again.
  148.  */
  149. extern char *current_file, *inherit_file;
  150.  
  151. /*
  152.  * The names and types of arguments and auto variables.
  153.  */
  154. char **local_names;
  155. unsigned short *type_of_locals;
  156. int current_number_of_locals = 0;
  157. int current_break_stack_need = 0  ,max_break_stack_need = 0;
  158.  
  159. /*
  160.  * The types of arguments when calling functions must be saved,
  161.  * to be used afterwards for checking. And because function calls
  162.  * can be done as an argument to a function calls,
  163.  * a stack of argument types is needed. This stack does not need to
  164.  * be freed between compilations, but will be reused.
  165.  */
  166. static struct mem_block type_of_arguments;
  167.  
  168. struct program *prog;    /* Is returned to the caller of yyparse */
  169.  
  170. void init_compiler(void)
  171. {
  172.     memset(&mem_block, 0, sizeof(struct mem_block) * NUMAREAS);
  173.     memset(&type_of_arguments, 0, sizeof(type_of_arguments));
  174. }
  175.  
  176. /*
  177.  * Compare two types, and return true if they are compatible.
  178.  */
  179. static int compatible_types(t1, t2)
  180.     int t1, t2;
  181. {
  182.     if (t1 == TYPE_UNKNOWN || t2 == TYPE_UNKNOWN)
  183.     return 0;
  184.     if (t1 == t2)
  185.     return 1;
  186.     if (t1 == TYPE_ANY || t2 == TYPE_ANY)
  187.     return 1;
  188.     if ((t1 & TYPE_MOD_POINTER) && (t2 & TYPE_MOD_POINTER)) {
  189.     if ((t1 & TYPE_MOD_MASK) == (TYPE_ANY|TYPE_MOD_POINTER) ||
  190.         (t2 & TYPE_MOD_MASK) == (TYPE_ANY|TYPE_MOD_POINTER))
  191.         return 1;
  192.     }
  193.     return 0;
  194. }
  195.  
  196. /*
  197.  * Add another argument type to the argument type stack
  198.  */
  199. INLINE
  200. static void add_arg_type(type)
  201.     unsigned short type;
  202. {
  203.     struct mem_block *mbp = &type_of_arguments;
  204.     while (mbp->current_size + sizeof type > mbp->max_size) {
  205.     mbp->max_size <<= 1;
  206.     mbp->block = xrealloc((char *)mbp->block, mbp->max_size);
  207.     }
  208.     memcpy(mbp->block + mbp->current_size, &type, sizeof type);
  209.     mbp->current_size += sizeof type;
  210. }
  211.  
  212. /*
  213.  * Pop the argument type stack 'n' elements.
  214.  */
  215. INLINE
  216. static void pop_arg_stack(n)
  217.     int n;
  218. {
  219.     type_of_arguments.current_size -= sizeof (unsigned short) * n;
  220. }
  221.  
  222. /*
  223.  * Get type of argument number 'arg', where there are
  224.  * 'n' arguments in total in this function call. Argument
  225.  * 0 is the first argument.
  226.  */
  227. INLINE
  228. int get_argument_type(arg, n)
  229.     int arg, n;
  230. {
  231.     return
  232.     ((unsigned short *)
  233.      (type_of_arguments.block + type_of_arguments.current_size))[arg - n];
  234. }
  235.  
  236. INLINE
  237. static void add_to_mem_block(n, data, size)
  238.     int n, size;
  239.     char *data;
  240. {
  241.     struct mem_block *mbp = &mem_block[n];
  242.     while (mbp->current_size + size > mbp->max_size) {
  243.     mbp->max_size <<= 1;
  244.     mbp->block = xrealloc((char *)mbp->block, mbp->max_size);
  245.     }
  246.     memcpy(mbp->block + mbp->current_size, data, size);
  247.     mbp->current_size += size;
  248. }
  249.  
  250. static void ins_byte(b)
  251.     char b;
  252. {
  253.     add_to_mem_block(A_PROGRAM, &b, 1);
  254. }
  255.  
  256. /*
  257.  * Store a 2 byte number. It is stored in such a way as to be sure
  258.  * that correct byte order is used, regardless of machine architecture.
  259.  * Also beware that some machines can't write a word to odd addresses.
  260.  */
  261. static void ins_short(l)
  262.     short l;
  263. {
  264.     add_to_mem_block(A_PROGRAM, (char *)&l + 0, 1);
  265.     add_to_mem_block(A_PROGRAM, (char *)&l + 1, 1);
  266. }
  267.  
  268. static void upd_short(offset, l)
  269.     int offset;
  270.     short l;
  271. {
  272.     mem_block[A_PROGRAM].block[offset + 0] = ((char *)&l)[0];
  273.     mem_block[A_PROGRAM].block[offset + 1] = ((char *)&l)[1];
  274. }
  275.  
  276. static short read_short(offset)
  277.     int offset;
  278. {
  279.     short l;
  280.  
  281.     ((char *)&l)[0] = mem_block[A_PROGRAM].block[offset + 0];
  282.     ((char *)&l)[1] = mem_block[A_PROGRAM].block[offset + 1];
  283.     return l;
  284. }
  285.  
  286. /*
  287.  * Store a 4 byte number. It is stored in such a way as to be sure
  288.  * that correct byte order is used, regardless of machine architecture.
  289.  */
  290. static void ins_long(l)
  291.     int l;
  292. {
  293.     add_to_mem_block(A_PROGRAM, (char *)&l+0, 1);
  294.     add_to_mem_block(A_PROGRAM, (char *)&l+1, 1);
  295.     add_to_mem_block(A_PROGRAM, (char *)&l+2, 1);
  296.     add_to_mem_block(A_PROGRAM, (char *)&l+3, 1);
  297. }
  298.  
  299. static void ins_f_byte(b)
  300.     unsigned int b;
  301. {
  302.     ins_byte((char)(b - F_OFFSET));
  303. }
  304.  
  305. /*
  306.  * Return the index of the function found, otherwise -1.
  307.  */
  308. static int defined_function(s, start)
  309.     char *s;
  310.     int start;
  311. {
  312.     int offset;
  313.     struct function *funp;
  314.     char *interned;
  315.  
  316.     if (interned = findstring(s))    /* Only search if amongst strings */
  317.     for (offset = start * sizeof (struct function);
  318.       offset < mem_block[A_FUNCTIONS].current_size;
  319.       offset += sizeof (struct function))
  320.     {
  321.         funp = (struct function *)&mem_block[A_FUNCTIONS].block[offset];
  322.         if (funp->flags & NAME_HIDDEN)
  323.         continue;
  324.         if (funp->name == interned)
  325.         return offset / sizeof (struct function);
  326.     }
  327.     return -1;
  328. }
  329.  
  330. /*
  331.  * A mechanism to remember addresses on a stack. The size of the stack is
  332.  * defined in config.h.
  333.  */
  334. static int comp_stackp;
  335. int *comp_stack;
  336.  
  337. static void push_address() {
  338.     if (comp_stackp >= COMPILER_STACK_SIZE) {
  339.     yyerror("Compiler stack overflow");
  340.     comp_stackp++;
  341.     return;
  342.     }
  343.     comp_stack[comp_stackp++] = mem_block[A_PROGRAM].current_size;
  344. }
  345.  
  346. static void push_explicit(address)
  347.     int address;
  348. {
  349.     if (comp_stackp >= COMPILER_STACK_SIZE) {
  350.     yyerror("Compiler stack overflow");
  351.     comp_stackp++;
  352.     return;
  353.     }
  354.     comp_stack[comp_stackp++] = address;
  355. }
  356.  
  357. static int pop_address() {
  358.     if (comp_stackp == 0)
  359.     fatal("Compiler stack underflow.\n");
  360.     if (comp_stackp > COMPILER_STACK_SIZE) {
  361.     --comp_stackp;
  362.     return 0;
  363.     }
  364.     return comp_stack[--comp_stackp];
  365. }
  366.  
  367. /*
  368.  * Patch a function definition of an inherited function, to what it really
  369.  * should be.
  370.  * The name of the function can be one of:
  371.  *    object::name
  372.  *    ::name
  373.  *    name
  374.  * Where 'object' is the name of the superclass.
  375.  */
  376. static void find_inherited(funp)
  377.     struct function *funp;
  378. {
  379.     int i;
  380.     struct inherit *ip;
  381.     int num_inherits, super_length;
  382.     char *real_name, *super_name = 0, *p;
  383.     char *interned;
  384.  
  385.     real_name = funp->name;
  386.     if (real_name[0] == ':')
  387.     real_name = real_name + 2;    /* There will be exactly two ':' */
  388.     else if (p = strchr(real_name, ':')) {
  389.     real_name = p+2;
  390.     super_name = funp->name;
  391.     super_length = real_name - super_name - 2;
  392.     }
  393.     num_inherits = mem_block[A_INHERITS].current_size /
  394.     sizeof (struct inherit);
  395.     ip = &((struct inherit *)mem_block[A_INHERITS].block)[num_inherits-1];
  396.     if (interned = findstring(real_name)) /* Only search if amongst strings */
  397.       for (; num_inherits > 0; ip--, num_inherits--) {
  398.     if (super_name) {
  399.         int l = strlen(ip->prog->name);    /* Including .c */
  400.         if (l - 2 < super_length)
  401.         continue;
  402.         if (strncmp(super_name, ip->prog->name + l - 2 - super_length,
  403.             super_length) != 0)
  404.         continue;
  405.     }
  406.     for (i=0; i < ip->prog->num_functions; i++) {
  407.         if (ip->prog->functions[i].flags & (NAME_UNDEFINED|NAME_HIDDEN))
  408.         continue;
  409.         if (ip->prog->functions[i].type & TYPE_MOD_PRIVATE)
  410.         continue;
  411.         if (ip->prog->functions[i].name != interned)
  412.         continue;
  413.         funp->offset = ip - (struct inherit *)mem_block[A_INHERITS].block;
  414.         funp->flags = ip->prog->functions[i].flags | NAME_INHERITED;
  415.         funp->num_local = ip->prog->functions[i].num_local;
  416.         funp->num_arg = ip->prog->functions[i].num_arg;
  417.         funp->type = ip->prog->functions[i].type;
  418.         funp->type |= funp->type & TYPE_MOD_PUBLIC ?
  419.         ip->type & ~TYPE_MOD_PRIVATE : ip->type;
  420.         funp->function_index_offset = i;
  421.         return;
  422.     }
  423.       }
  424.     return;
  425. }
  426.  
  427. void replace_function(num, name, num_arg, num_local, offset, flags, type)
  428. int num, num_arg, num_local, offset, flags, type;
  429. char *name;
  430. {
  431.     struct function *funp;
  432.  
  433.     funp = (struct function *)(mem_block[A_FUNCTIONS].block) + num;
  434.     if (!(funp->flags & NAME_UNDEFINED) &&
  435.     !(flags & NAME_PROTOTYPE) &&
  436.     !(funp->flags & NAME_INHERITED))
  437.     {
  438.     char buff[500];
  439.     sprintf(buff, "Redeclaration of function %s.", name);
  440.     yyerror(buff);
  441.     return;
  442.     }
  443.     /*
  444.      * It was either an undefined but used function, or an inherited
  445.      * function. In both cases, we now consider this to be THE new
  446.      * definition. It might also have been a prototype to an already
  447.      * defined function.
  448.      *
  449.      * Check arguments only when types are supposed to be tested,
  450.      * and if this function really has been defined already.
  451.      *
  452.      * 'nomask' functions may not be redefined.
  453.      */
  454.     if ((funp->type & TYPE_MOD_NO_MASK) &&
  455.     !(funp->flags & NAME_PROTOTYPE) &&
  456.     !(flags & NAME_PROTOTYPE))
  457.     {
  458.     char *p = (char *)alloca(80 + strlen(name));
  459.     sprintf(p, "Illegal to redefine 'nomask' function \"%s\"",name);
  460.     yyerror(p);
  461.     }
  462.     if (exact_types && funp->type != TYPE_UNKNOWN) {
  463.     int i;
  464.     if (funp->num_arg != num_arg && !(funp->type & TYPE_MOD_VARARGS))
  465.         yyerror("Incorrect number of arguments.");
  466.     else if (!(funp->flags & NAME_STRICT_TYPES))
  467.         yyerror("Called function not compiled with type testing.");
  468.     else {
  469.         /* Now check that argument types wasn't changed. */
  470.         for (i=0; i < num_arg; i++) {
  471.         }
  472.     }
  473.     }
  474.     /* If it was yet another prototype, then simply return. */
  475.     if (flags & NAME_PROTOTYPE)
  476.     return;
  477.     funp->num_arg = num_arg;
  478.     funp->num_local = num_local;
  479.     funp->flags = flags;
  480.     funp->offset = offset;
  481.     funp->function_index_offset = 0;
  482.     funp->type = type;
  483.     if (exact_types)
  484.     funp->flags |= NAME_STRICT_TYPES;
  485.     return;
  486. }
  487.  
  488. /*
  489.  * Define a new function. Note that this function is called at least twice
  490.  * for alll function definitions. First as a prototype, then as the real
  491.  * function. Thus, there are tests to avoid generating error messages more
  492.  * than once by looking at (flags & NAME_PROTOTYPE).
  493.  */
  494. static int define_new_function(name, num_arg, num_local, offset, flags, type)
  495.     char *name;
  496.     int num_arg, num_local;
  497.     int offset, flags, type;
  498. {
  499.     int num;
  500.     struct function fun;
  501.     unsigned short argument_start_index;
  502.  
  503.     num = defined_function(name, 0);
  504.     if (num >= 0) {
  505.     int save_num;
  506.  
  507.     /*
  508.      * The function was already defined. It may be one of several reasons:
  509.      *
  510.      * 1.    There has been a prototype.
  511.      * 2.    There was the same function defined by inheritance.
  512.      * 3.    This function has been called, but not yet defined.
  513.      * 4.    The function is doubly defined.
  514.      * 5.    A "late" prototype has been encountered.
  515.      */
  516.     do {
  517.         replace_function(num, name, num_arg, num_local, offset, flags,type);
  518.         save_num = num;
  519.         num = defined_function(name, num+1);
  520.     } while (num >= 0);
  521.     return save_num;
  522.     }
  523.     if (strcmp(name, "heart_beat") == 0)
  524.     heart_beat = mem_block[A_FUNCTIONS].current_size /
  525.         sizeof (struct function);
  526.     fun.name = make_shared_string(name);
  527.     fun.offset = offset;
  528.     fun.flags = flags;
  529.     fun.num_arg = num_arg;
  530.     fun.num_local = num_local;
  531.     fun.function_index_offset = 0;
  532.     fun.type = type;
  533.     if (exact_types)
  534.     fun.flags |= NAME_STRICT_TYPES;
  535.     num = mem_block[A_FUNCTIONS].current_size / sizeof fun;
  536.     /* Number of local variables will be updated later */
  537.     add_to_mem_block(A_FUNCTIONS, (char *)&fun, sizeof fun);
  538.  
  539.     if (exact_types == 0 || num_arg == 0) {
  540.     argument_start_index = INDEX_START_NONE;
  541.     } else {
  542.     int i;
  543.  
  544.     /*
  545.      * Save the start of argument types.
  546.      */
  547.     argument_start_index =
  548.         mem_block[A_ARGUMENT_TYPES].current_size /
  549.         sizeof (unsigned short);
  550.     for (i=0; i < num_arg; i++) {
  551.         add_to_mem_block(A_ARGUMENT_TYPES, &type_of_locals[i],
  552.                  sizeof type_of_locals[i]);
  553.     }
  554.     }
  555.     add_to_mem_block(A_ARGUMENT_INDEX, &argument_start_index,
  556.              sizeof argument_start_index);
  557.     return num;
  558. }
  559.  
  560. static void define_variable(name, type, flags)
  561.     char *name;
  562.     int type;
  563.     int flags;
  564. {
  565.     struct variable dummy;
  566.     int n;
  567.  
  568.     n = check_declared(name);
  569.     if (n != -1 && (VARIABLE(n)->type & TYPE_MOD_NO_MASK)) {
  570.     char *p = (char *)alloca(80 + strlen(name));
  571.     sprintf(p, "Illegal to redefine 'nomask' variable \"%s\"", name);
  572.     yyerror(p);
  573.     }
  574.     dummy.name = make_shared_string(name);
  575.     dummy.type = type;
  576.     dummy.flags = flags;
  577.     add_to_mem_block(A_VARIABLES, (char *)&dummy, sizeof dummy);
  578. }
  579.  
  580. short store_prog_string(str)
  581.     char *str;
  582. {
  583.     short i;
  584.     char **p;
  585.  
  586.     p = (char **) mem_block[A_STRINGS].block;
  587.     str = make_shared_string(str);
  588.     for (i=mem_block[A_STRINGS].current_size / sizeof str -1; i>=0; --i)
  589.     if (p[i] == str)  {
  590.         free_string(str); /* Needed as string is only free'ed once. */
  591.         return i;
  592.     }
  593.  
  594.     add_to_mem_block(A_STRINGS, &str, sizeof str);
  595.     return mem_block[A_STRINGS].current_size / sizeof str - 1;
  596. }
  597.  
  598. void add_to_case_heap(block_index,entry)
  599.     int block_index;
  600.     struct case_heap_entry *entry;
  601. {
  602.     char *heap_start;
  603.     int offset,parent;
  604.     int current_heap;
  605.  
  606.     if ( block_index == A_CASE_NUMBERS )
  607.         current_heap = current_case_number_heap;
  608.     else
  609.         current_heap = current_case_string_heap;
  610.     offset = mem_block[block_index].current_size - current_heap;
  611.     add_to_mem_block(block_index, (char*)entry, sizeof(*entry) );
  612.     heap_start = mem_block[block_index].block + current_heap;
  613.     for ( ; offset; offset = parent ) {
  614.         parent = ( offset - sizeof(struct case_heap_entry) ) >> 1 ;
  615.         CASE_HEAP_ENTRY_ALIGN(parent);
  616.         if ( ((struct case_heap_entry*)(heap_start+offset))->key <
  617.              ((struct case_heap_entry*)(heap_start+parent))->key )
  618.         {
  619.             *(struct case_heap_entry*)(heap_start+offset) =
  620.             *(struct case_heap_entry*)(heap_start+parent);
  621.             *(struct case_heap_entry*)(heap_start+parent) = *entry;
  622.         }
  623.     }
  624. }
  625.  
  626. /*
  627.  * Arrange a jump to the current position for the initialization code
  628.  * to continue.
  629.  */
  630. static void transfer_init_control() {
  631.     if (mem_block[A_PROGRAM].current_size - 2 == last_initializer_end)
  632.     mem_block[A_PROGRAM].current_size -= 3;
  633.     else {
  634.     /*
  635.      * Change the address of the last jump after the last
  636.      * initializer to this point.
  637.      */
  638.     upd_short(last_initializer_end,
  639.           mem_block[A_PROGRAM].current_size);
  640.     }
  641. }
  642.  
  643. void add_new_init_jump();
  644. %}
  645.  
  646. /*
  647.  * These values are used by the stack machine, and can not be directly
  648.  * called from LPC.
  649.  */
  650. %token F_JUMP F_JUMP_WHEN_ZERO F_JUMP_WHEN_NON_ZERO
  651. %token F_POP_VALUE F_DUP
  652. %token F_STORE F_CALL_FUNCTION_BY_ADDRESS
  653. %token F_PUSH_IDENTIFIER_LVALUE F_PUSH_LOCAL_VARIABLE_LVALUE
  654. %token F_PUSH_INDEXED_LVALUE F_INDIRECT F_INDEX
  655. %token F_CONST0 F_CONST1
  656.  
  657. /*
  658.  * These are the predefined functions that can be accessed from LPC.
  659.  */
  660.  
  661. %token F_IF F_IDENTIFIER F_LAND F_LOR F_STATUS
  662. %token F_RETURN F_STRING
  663. %token F_INC F_DEC
  664. %token F_POST_INC F_POST_DEC F_COMMA
  665. %token F_NUMBER F_ASSIGN F_INT F_ADD F_SUBTRACT F_MULTIPLY
  666. %token F_DIVIDE F_LT F_GT F_EQ F_GE F_LE
  667. %token F_NE
  668. %token F_ADD_EQ F_SUB_EQ F_DIV_EQ F_MULT_EQ
  669. %token F_NEGATE
  670. %token F_SUBSCRIPT F_WHILE F_BREAK
  671. %token F_DO F_FOR F_SWITCH
  672. %token F_SSCANF F_PARSE_COMMAND F_STRING_DECL F_LOCAL_NAME
  673. %token F_ELSE F_DESCRIBE
  674. %token F_CONTINUE
  675. %token F_MOD F_MOD_EQ F_INHERIT F_COLON_COLON
  676. %token F_STATIC
  677. %token F_ARROW F_AGGREGATE F_M_AGGREGATE
  678. %token F_COMPL F_AND F_AND_EQ F_OR F_OR_EQ F_XOR F_XOR_EQ
  679. %token F_LSH F_LSH_EQ F_RSH F_RSH_EQ
  680. %token F_CATCH
  681. %token F_OBJECT F_VOID F_MIXED F_PRIVATE F_NO_MASK F_NOT F_MAPPING
  682. %token F_PROTECTED F_PUBLIC
  683. %token F_VARARGS
  684. %token F_ADD_ACTION
  685. %token F_ADD_VERB
  686. %token F_ADD_WORTH
  687. %token F_ADD_XVERB
  688. %token F_ALL_INVENTORY
  689. %token F_ALLOCATE
  690. %token F_BREAK_POINT
  691. %token F_CALL_OTHER
  692. %token F_CALL_OUT
  693. %token F_CALL_OUT_INFO
  694. %token F_CAPITALIZE
  695. %token F_CAT
  696. %token F_CINDENT
  697. %token F_CLEAR_BIT
  698. %token F_CLONE_OBJECT
  699. %token F_COMMAND
  700. %token F_CREATE_WIZARD
  701. %token F_CREATOR
  702. %token F_CRYPT
  703. %token F_CTIME
  704. %token F_DEBUG_INFO
  705. %token F_DEEP_INVENTORY
  706. %token F_DESTRUCT
  707. %token F_DISABLE_COMMANDS
  708. %token F_ED
  709. %token F_ENABLE_COMMANDS
  710. %token F_ENVIRONMENT
  711. %token F_EXEC
  712. %token F_EXPLODE
  713. %token F_EXTRACT
  714. %token F_FILE_NAME
  715. %token F_FILE_SIZE
  716. %token F_FILTER_ARRAY
  717. %token F_FILTER_MAPPING
  718. %token F_FIND_CALL_OUT
  719. %token F_FIND_LIVING
  720. %token F_FIND_OBJECT
  721. %token F_FIND_PLAYER
  722. %token F_FIRST_INVENTORY
  723. %token F_FUNCTION_EXISTS
  724. %token F_GET_DIR
  725. %token F_IMPLODE
  726. %token F_INHERIT_LIST
  727. %token F_INPUT_TO
  728. %token F_INTERACTIVE
  729. %token F_INTP
  730. %token F_LIVING
  731. %token F_LOCALCMD
  732. %token F_LOG_FILE
  733. %token F_LOWER_CASE
  734. %token F_M_DELETE
  735. %token F_M_INDICES
  736. %token F_M_SIZEOF
  737. %token F_M_VALUES
  738. %token F_MAP_ARRAY
  739. %token F_MAP_MAPPING
  740. %token F_MAPPINGP
  741. %token F_MASTER_OBJECT
  742. %token F_MEMBER_ARRAY
  743. %token F_MKDIR
  744. %token F_MKMAPPING
  745. %token F_MOVE_OBJECT
  746. %token F_NEXT_INVENTORY
  747. %token F_NOTIFY_FAIL
  748. %token F_OBJECTP
  749. %token F_POINTERP
  750. %token F_PRESENT
  751. %token F_PREVIOUS_OBJECT
  752. %token F_PRINTF
  753. %token F_PROCESS_STRING
  754. %token F_QUERY_HEART_BEAT
  755. %token F_QUERY_HOST_NAME
  756. %token F_QUERY_IDLE
  757. %token F_QUERY_IP_NAME
  758. %token F_QUERY_IP_NUMBER
  759. %token F_QUERY_LOAD_AVERAGE
  760. %token F_QUERY_SNOOP
  761. %token F_QUERY_VERB
  762. %token F_RANDOM
  763. %token F_READ_BYTES
  764. %token F_READ_FILE
  765. %token F_REGEXP
  766. %token F_REMOVE_CALL_OUT
  767. %token F_RESTORE_OBJECT
  768. %token F_RM
  769. %token F_RMDIR
  770. %token F_SAVE_OBJECT
  771. %token F_SAY
  772. %token F_SET_BIT
  773. %token F_SET_HEART_BEAT
  774. %token F_SET_LIGHT
  775. %token F_SET_LIVING_NAME
  776. %token F_SHADOW
  777. %token F_SHOUT
  778. %token F_SHUTDOWN
  779. %token F_SIZEOF
  780. %token F_SNOOP
  781. %token F_SORT_ARRAY
  782. %token F_SPRINTF
  783. %token F_STRINGP
  784. %token F_STRLEN
  785. %token F_SWAP
  786. %token F_TAIL
  787. %token F_TELL_OBJECT
  788. %token F_TELL_ROOM
  789. %token F_TEST_BIT
  790. %token F_THIS_INTERACTIVE
  791. %token F_THIS_OBJECT
  792. %token F_THIS_PLAYER
  793. %token F_THROW
  794. %token F_TIME
  795. %token F_TRACE
  796. %token F_TRACEPREFIX
  797. %token F_TRANSFER
  798. %token F_UNIQUE_ARRAY
  799. %token F_USERS
  800. %token F_VERSION
  801. %token F_WIZLIST
  802. %token F_WRITE
  803. %token F_WRITE_BYTES
  804. %token F_WRITE_FILE
  805. /*
  806.  * These are token values that needn't have an associated code for the
  807.  * compiled file
  808.  */
  809.  
  810. %token F_CASE F_DEFAULT F_RANGE
  811.  
  812. %union
  813. {
  814.     int number;
  815.     unsigned int address;    /* Address of an instruction */
  816.     char *string;
  817.     short type;
  818.     struct { int key; char block; } case_label;
  819.     struct function *funp;
  820. }
  821.  
  822. %type <number> assign F_NUMBER constant F_LOCAL_NAME expr_list
  823. %type <number> const1 const2 const3 const4 const5 const6 const7 const8 const9
  824. %type <number> lvalue_list argument type basic_type optional_star expr_list2
  825. %type <number> type_modifier type_modifier_list opt_basic_type block_or_semi
  826. %type <number> argument_list m_expr_list m_expr_list2
  827. %type <string> F_IDENTIFIER F_STRING string_con1 string_constant function_name any_ident
  828.  
  829. %type <case_label> case_label
  830.  
  831. /* The following symbos return type information */
  832.  
  833. %type <type> function_call lvalue string cast expr28 expr01 comma_expr
  834. %type <type> expr2 expr211 expr1 expr212 expr213 expr24 expr22 expr23 expr25
  835. %type <type> expr27 expr28 expr24 expr3 expr31 expr4 number expr0
  836. %%
  837.  
  838. all: program;
  839.  
  840. program: program def possible_semi_colon
  841.        |     /* empty */ ;
  842.  
  843. possible_semi_colon: /* empty */
  844.                    | ';' { yyerror("Extra ';'. Ignored."); };
  845.  
  846. inheritance: type_modifier_list F_INHERIT F_STRING ';'
  847.         {
  848.             struct object *ob;
  849.             struct inherit inherit;
  850.             int initializer;
  851.  
  852.             ob = find_object2($3);
  853.             if (ob == 0) {
  854.             inherit_file = $3;
  855.             /* Return back to load_object() */
  856.             YYACCEPT;
  857.             }
  858.             xfree($3);
  859.             if (ob->flags & O_APPROVED)
  860.             approved_object = 1;
  861.             inherit.prog = ob->prog;
  862.             inherit.function_index_offset =
  863.             mem_block[A_FUNCTIONS].current_size /
  864.                 sizeof (struct function);
  865.             inherit.variable_index_offset =
  866.             mem_block[A_VARIABLES].current_size /
  867.                 sizeof (struct variable);
  868.             inherit.type = $1;
  869.             add_to_mem_block(A_INHERITS, &inherit, sizeof inherit);
  870.             copy_variables(ob->prog, $1);
  871.             initializer = copy_functions(ob->prog, $1);
  872.             if (initializer > 0) {
  873.             struct function *funp;
  874.             int f;
  875.             f = define_new_function("::__INIT", 0, 0, 0, 0, 0);
  876.             funp = FUNCTION(f);
  877.             funp->offset = mem_block[A_INHERITS].current_size /
  878.                 sizeof (struct inherit) - 1;
  879.             funp->flags = NAME_STRICT_TYPES |
  880.                 NAME_INHERITED | NAME_HIDDEN;
  881.             funp->type = TYPE_VOID;
  882.             funp->function_index_offset = initializer;
  883.             transfer_init_control();
  884.             ins_f_byte(F_CALL_FUNCTION_BY_ADDRESS);
  885.             ins_short(f);
  886.             ins_byte(0);    /* Actual number of arguments */
  887.             ins_f_byte(F_POP_VALUE);
  888.             add_new_init_jump();
  889.             }
  890.         }
  891.  
  892. number: F_NUMBER
  893.     {
  894.         if ( $1 == 0 ) {
  895.         ins_f_byte(F_CONST0); $$ = TYPE_ANY;
  896.         } else if ( $1 == 1 ) {
  897.         ins_f_byte(F_CONST1); $$ = TYPE_NUMBER;
  898.         } else {
  899.         ins_f_byte(F_NUMBER); ins_long($1); $$ = TYPE_NUMBER;
  900.         }
  901.     } ;
  902.  
  903. optional_star: /* empty */ { $$ = 0; } | '*' { $$ = TYPE_MOD_POINTER; } ;
  904.  
  905. block_or_semi: block { $$ = 0; } | ';' { $$ = ';'; } ;
  906.  
  907. def: type optional_star F_IDENTIFIER
  908.     {
  909.         /* Save start of function. */
  910.         push_explicit(mem_block[A_PROGRAM].current_size);
  911.  
  912.         if ($1 & TYPE_MOD_MASK) {
  913.         exact_types = $1 | $2;
  914.         } else {
  915.         if (pragma_strict_types)
  916.             yyerror("\"#pragma strict_types\" requires type of function");
  917.         exact_types = 0;
  918.         }
  919.     }
  920.     '(' argument ')'
  921.     {
  922.         /*
  923.          * Define a prototype. If it is a real function, then the
  924.          * prototype will be replaced below.
  925.          */
  926.         define_new_function($3, $6, 0, 0,
  927.                 NAME_UNDEFINED|NAME_PROTOTYPE, $1 | $2);
  928.     }
  929.         block_or_semi
  930.     {
  931.         /* Either a prototype or a block */
  932.         if ($9 == ';') {
  933.         (void)pop_address(); /* Not used here */
  934.         } else {
  935.         define_new_function($3, $6, current_number_of_locals - $6+
  936.             ( max_break_stack_need -1 ) / sizeof(struct svalue) +1,
  937.             pop_address(), 0, $1 | $2);
  938.         ins_f_byte(F_CONST0); ins_f_byte(F_RETURN);
  939.         }
  940.         free_all_local_names();
  941.         xfree($3);        /* Value was copied above */
  942.     }
  943.    | type name_list ';' { if ($1 == 0) yyerror("Missing type"); }
  944.    | inheritance ;
  945.  
  946. new_arg_name: type optional_star F_IDENTIFIER
  947.     {
  948.         if (exact_types && $1 == 0) {
  949.         yyerror("Missing type for argument");
  950.         add_local_name($3, TYPE_ANY);    /* Supress more errors */
  951.         } else {
  952.         add_local_name($3, $1 | $2);
  953.         }
  954.     }
  955.       | type F_LOCAL_NAME
  956.         {yyerror("Illegal to redeclare local name"); } ;
  957.  
  958. argument: /* empty */ { $$ = 0; }
  959.       | argument_list ;
  960.  
  961. argument_list: new_arg_name { $$ = 1; }
  962.          | argument_list ',' new_arg_name { $$ = $1 + 1; } ;
  963.  
  964. type_modifier: F_NO_MASK { $$ = TYPE_MOD_NO_MASK; }
  965.          | F_STATIC { $$ = TYPE_MOD_STATIC; }
  966.          | F_PRIVATE { $$ = TYPE_MOD_PRIVATE; }
  967.          | F_PUBLIC { $$ = TYPE_MOD_PUBLIC; }
  968.          | F_VARARGS { $$ = TYPE_MOD_VARARGS; }
  969.          | F_PROTECTED { $$ = TYPE_MOD_PROTECTED; } ;
  970.  
  971. type_modifier_list: /* empty */ { $$ = 0; }
  972.           | type_modifier type_modifier_list { $$ = $1 | $2; } ;
  973.  
  974. type: type_modifier_list opt_basic_type { $$ = $1 | $2; current_type = $$; } ;
  975.  
  976. cast: '(' basic_type optional_star ')'
  977.     {
  978.         $$ = $2 | $3;
  979.     } ;
  980.  
  981. opt_basic_type: basic_type | /* empty */ { $$ = TYPE_UNKNOWN; } ;
  982.  
  983. basic_type: F_STATUS { $$ = TYPE_NUMBER; current_type = $$; }
  984.     | F_INT { $$ = TYPE_NUMBER; current_type = $$; }
  985.     | F_STRING_DECL { $$ = TYPE_STRING; current_type = $$; }
  986.     | F_OBJECT { $$ = TYPE_OBJECT; current_type = $$; }
  987.     | F_VOID {$$ = TYPE_VOID; current_type = $$; }
  988.     | F_MIXED { $$ = TYPE_ANY; current_type = $$; } 
  989.     | F_MAPPING { $$ = TYPE_MAPPING; current_type = $$; };
  990.  
  991. name_list: new_name
  992.      | new_name ',' name_list;
  993.  
  994. new_name: optional_star F_IDENTIFIER
  995.     {
  996.         define_variable($2, current_type | $1, 0);
  997.         xfree($2);
  998.     }
  999. | optional_star F_IDENTIFIER
  1000.     {
  1001.         int var_num;
  1002.         define_variable($2, current_type | $1, 0);
  1003.         var_num = verify_declared($2);
  1004.         transfer_init_control();
  1005.         ins_f_byte(F_PUSH_IDENTIFIER_LVALUE);
  1006.         ins_byte(var_num);
  1007.     }
  1008.     '=' expr0
  1009.     {
  1010.         if (!compatible_types((current_type | $1) & TYPE_MOD_MASK, $5)){
  1011.         char buff[100];
  1012.         sprintf(buff, "Type mismatch %s when initializing %s",
  1013.             get_two_types(current_type | $1, $5), $2);
  1014.         yyerror(buff);
  1015.         }
  1016.         ins_f_byte(F_ASSIGN);
  1017.         ins_f_byte(F_POP_VALUE);
  1018.         add_new_init_jump();
  1019.         xfree($2);
  1020.     } ;
  1021. block: '{' local_declarations statements '}'
  1022.     { ; };
  1023.  
  1024. local_declarations: /* empty */
  1025.           | local_declarations basic_type local_name_list ';' ;
  1026.  
  1027. new_local_name: optional_star F_IDENTIFIER
  1028.     {
  1029.         add_local_name($2, current_type | $1);
  1030.     } ;
  1031.  
  1032. local_name_list: new_local_name
  1033.     | new_local_name ',' local_name_list ;
  1034.  
  1035. statements: /* empty */
  1036.       | statement statements
  1037.       | error ';' ;
  1038.  
  1039. statement: comma_expr ';'
  1040.     {
  1041.         ins_f_byte(F_POP_VALUE);
  1042.         if (d_flag)
  1043.         ins_f_byte(F_BREAK_POINT);
  1044.         /* if (exact_types && !TYPE($1,TYPE_VOID))
  1045.         yyerror("Value thrown away"); */
  1046.     }
  1047.      | cond | while | do | for | switch | case | default | return ';'
  1048.      | block
  1049.        | /* empty */ ';'
  1050.      | F_BREAK ';'    /* This code is a jump to a jump */
  1051.         {
  1052.             if (current_break_address == 0)
  1053.             yyerror("break statement outside loop");
  1054.             if (current_break_address & BREAK_ON_STACK) {
  1055.             ins_f_byte(F_BREAK);
  1056.             } else {
  1057.                 ins_f_byte(F_JUMP); ins_short(current_break_address);
  1058.             }
  1059.         }
  1060.      | F_CONTINUE ';'    /* This code is a jump to a jump */
  1061.         {
  1062.             if (current_continue_address == 0)
  1063.             yyerror("continue statement outside loop");
  1064.             ins_f_byte(F_JUMP); ins_short(current_continue_address);
  1065.         }
  1066.          ;
  1067.  
  1068. while:  {   push_explicit(current_continue_address);
  1069.         push_explicit(current_break_address);
  1070.         current_continue_address = mem_block[A_PROGRAM].current_size;
  1071.     } F_WHILE '(' comma_expr ')'
  1072.     {
  1073.         ins_f_byte(F_JUMP_WHEN_NON_ZERO); ins_short(0);    /* to block */
  1074.         current_break_address = mem_block[A_PROGRAM].current_size;
  1075.         ins_f_byte(F_JUMP); ins_short(0);    /* Exit loop */
  1076.         upd_short(current_break_address-2,
  1077.               mem_block[A_PROGRAM].current_size);
  1078.     }
  1079.        statement
  1080.     {
  1081.       ins_f_byte(F_JUMP); ins_short(current_continue_address);
  1082.       upd_short(current_break_address+1,
  1083.             mem_block[A_PROGRAM].current_size);
  1084.       current_break_address = pop_address();
  1085.       current_continue_address = pop_address();
  1086.         }
  1087.  
  1088. do: {
  1089.         int tmp_save;
  1090.         push_explicit(current_continue_address);
  1091.     push_explicit(current_break_address);
  1092.     /* Jump to start of loop. */
  1093.     ins_f_byte(F_JUMP); tmp_save = mem_block[A_PROGRAM].current_size;
  1094.     ins_short(0);
  1095.     current_break_address = mem_block[A_PROGRAM].current_size;
  1096.     /* Jump to end of loop. All breaks go through this one. */
  1097.     ins_f_byte(F_JUMP); push_address(); ins_short(0);
  1098.     current_continue_address = mem_block[A_PROGRAM].current_size;
  1099.     upd_short(tmp_save, current_continue_address);
  1100.         push_address();
  1101.     
  1102.     } F_DO statement F_WHILE '(' comma_expr ')' ';'
  1103.     {
  1104.     ins_f_byte(F_JUMP_WHEN_NON_ZERO); ins_short(pop_address());
  1105.     /* Fill in the break jump address in the beginning of the loop. */
  1106.     upd_short(pop_address(), mem_block[A_PROGRAM].current_size);
  1107.     current_break_address = pop_address();
  1108.     current_continue_address = pop_address();
  1109.     }
  1110.  
  1111. for: F_FOR '('      { push_explicit(current_continue_address);
  1112.             push_explicit(current_break_address); }
  1113.      for_expr ';' {   ins_f_byte(F_POP_VALUE);
  1114.               push_address();
  1115.           }
  1116.      for_expr ';' {
  1117.             ins_f_byte(F_JUMP_WHEN_NON_ZERO);
  1118.             ins_short(0);    /* Jump to block of block */
  1119.             current_break_address = mem_block[A_PROGRAM].current_size;
  1120.             ins_f_byte(F_JUMP); ins_short(0);    /* Out of loop */
  1121.              current_continue_address =
  1122.             mem_block[A_PROGRAM].current_size;
  1123.           }
  1124.      for_expr ')' {
  1125.              ins_f_byte(F_POP_VALUE);
  1126.             ins_f_byte(F_JUMP); ins_short(pop_address());
  1127.             /* Here starts the block. */
  1128.             upd_short(current_break_address-2,
  1129.                   mem_block[A_PROGRAM].current_size);
  1130.           }
  1131.      statement
  1132.    {
  1133.        ins_f_byte(F_JUMP); ins_short(current_continue_address);
  1134.        /* Now, the address of the end of the block is known. */
  1135.        upd_short(current_break_address+1, mem_block[A_PROGRAM].current_size);
  1136.        current_break_address = pop_address();
  1137.        current_continue_address = pop_address();
  1138.    }
  1139.  
  1140. for_expr: /* EMPTY */ { ins_f_byte(F_CONST1); }
  1141.         | comma_expr;
  1142.  
  1143. switch: F_SWITCH '(' comma_expr ')'
  1144.     {
  1145.         current_break_stack_need += sizeof(short);
  1146.         if ( current_break_stack_need > max_break_stack_need )
  1147.             max_break_stack_need = current_break_stack_need;
  1148.     push_explicit(current_case_number_heap);
  1149.     push_explicit(current_case_string_heap);
  1150.     push_explicit(zero_case_label);
  1151.     push_explicit(current_break_address);
  1152.     ins_f_byte(F_SWITCH);
  1153.     ins_byte(0xff); /* kind of table */
  1154.     current_case_number_heap = mem_block[A_CASE_NUMBERS].current_size;
  1155.     current_case_string_heap = mem_block[A_CASE_STRINGS].current_size;
  1156.     zero_case_label = NO_STRING_CASE_LABELS;
  1157.     ins_short(0); /* address of table */
  1158.     current_break_address = mem_block[A_PROGRAM].current_size |
  1159.                 BREAK_ON_STACK | BREAK_FROM_CASE ;
  1160.     ins_short(0); /* break address to push, table is entered before */
  1161.     ins_short(0); /* default address */
  1162.     }
  1163.       statement
  1164.     {
  1165.     char *heap_start;
  1166.     int heap_end_offs;
  1167.     int i,o;
  1168.     int current_key,last_key;
  1169.     /* int size_without_table; */
  1170.     int block_index;
  1171.     int current_case_heap;
  1172.     int lookup_start;
  1173.     int lookup_start_key;
  1174.  
  1175.     current_break_address &= ~(BREAK_ON_STACK|BREAK_FROM_CASE);
  1176.  
  1177.     if ( !read_short(current_break_address+2 ) )
  1178.         upd_short(current_break_address+2,     /* no default given ->  */
  1179.           mem_block[A_PROGRAM].current_size);  /* create one           */
  1180.  
  1181.     /* it isn't unusual that the last case/default has no break */
  1182.     ins_f_byte(F_BREAK);
  1183.     if(zero_case_label & (NO_STRING_CASE_LABELS|SOME_NUMERIC_CASE_LABELS)){
  1184.         block_index = A_CASE_NUMBERS;
  1185.         current_case_heap = current_case_number_heap;
  1186.     } else {
  1187.         block_index = A_CASE_STRINGS;
  1188.         current_case_heap = current_case_string_heap;
  1189.         if (zero_case_label&0xffff) {
  1190.         struct case_heap_entry temp;
  1191.  
  1192.         temp.key = (int) ZERO_AS_STR_CASE_LABEL;
  1193.         temp.addr = zero_case_label;
  1194.         temp.line = 0; /* if this is accessed later, something is
  1195.                 * really wrong                  */
  1196.         add_to_case_heap(A_CASE_STRINGS,&temp);
  1197.         }
  1198.     }
  1199.     heap_start = mem_block[block_index].block + current_case_heap ;
  1200.     heap_end_offs = mem_block[block_index].current_size -current_case_heap;
  1201.     if (!heap_end_offs) yyerror("switch without case not supported");
  1202.  
  1203.         /* add a dummy entry so that we can always
  1204.         * assume we have no or two childs
  1205.         */
  1206.         add_to_mem_block(block_index, "\0\0\0\0\0\0\0\0",
  1207.             sizeof(struct case_heap_entry) );
  1208.  
  1209.         /* read out the heap and build a sorted table */
  1210.     /* the table could be optimized better, but let's first see
  1211.     * how much switch is used at all when it is full-featured...
  1212.     */
  1213.     mem_block[A_CASE_LABELS].current_size = 0;
  1214.     lookup_start = 0;
  1215.     lookup_start_key = ((struct case_heap_entry*)heap_start)->key;
  1216.         for( ; ((struct case_heap_entry*)heap_start)->addr; )
  1217.         {
  1218.             int offset;
  1219.         int curr_line,last_line;
  1220.         unsigned short current_addr,last_addr = 0xffff;
  1221.         int range_start;
  1222.  
  1223.             current_key = ((struct case_heap_entry*)heap_start)->key ;
  1224.             curr_line = ((struct case_heap_entry*)heap_start)->line ;
  1225.             current_addr = ((struct case_heap_entry*)heap_start)->addr ;
  1226.             if ( current_key == last_key &&
  1227.               mem_block[A_CASE_LABELS].current_size )
  1228.             {
  1229.                 char buf[90];
  1230.  
  1231.                 sprintf(buf,"Duplicate case in line %d and %d",
  1232.             last_line, curr_line);
  1233.                 yyerror(buf);
  1234.             }
  1235.         if (curr_line) {
  1236.         if (last_addr == 1) {
  1237.                     char buf[120];
  1238.     
  1239.             sprintf(buf,
  1240. "Discontinued case label list range, line %d by line %d",
  1241.               last_line, curr_line);
  1242.                     yyerror(buf);
  1243.         }
  1244.           else if (current_key == last_key + 1
  1245.             && current_addr == last_addr) {
  1246.             if (mem_block[A_CASE_LABELS].current_size
  1247.               != range_start + 6) {
  1248.               *(short*)(mem_block[A_CASE_LABELS].block+range_start+4)
  1249.             =1;
  1250.               mem_block[A_CASE_LABELS].current_size = range_start + 6;
  1251.             }
  1252.         } else {
  1253.             range_start = mem_block[A_CASE_LABELS].current_size;
  1254.         }
  1255.         }
  1256.             last_key = current_key;
  1257.         last_line = curr_line;
  1258.         last_addr = current_addr;
  1259.         add_to_mem_block(A_CASE_LABELS,
  1260.                 (char *)¤t_key, sizeof(long) );
  1261.         add_to_mem_block(A_CASE_LABELS,
  1262.         (char *)¤t_addr, sizeof(short) );
  1263.             for ( offset = 0; ; )
  1264.             {
  1265.  
  1266.                 int child1,child2;
  1267.  
  1268.                 child1 = ( offset << 1 ) + sizeof(struct case_heap_entry);
  1269.                 child2 = child1 + sizeof(struct case_heap_entry);
  1270.                 if ( child1 >= heap_end_offs ) break;
  1271.                 if ( ((struct case_heap_entry*)(heap_start+child1))->addr &&
  1272.                   ( !((struct case_heap_entry*)(heap_start+child2))->addr ||
  1273.                    ((struct case_heap_entry*)(heap_start+child1))->key <=
  1274.                    ((struct case_heap_entry*)(heap_start+child2))->key  ) )
  1275.                 {
  1276.                     *(struct case_heap_entry*)(heap_start+offset) =
  1277.                     *(struct case_heap_entry*)(heap_start+child1);
  1278.                     offset = child1;
  1279.                 } else
  1280.                     if (((struct case_heap_entry*)(heap_start+child2))->addr ) {
  1281.                         *(struct case_heap_entry*)(heap_start+offset) =
  1282.                         *(struct case_heap_entry*)(heap_start+child2);
  1283.                         offset = child2;
  1284.                     } else break;
  1285.             }
  1286.             ((struct case_heap_entry*)(heap_start+offset))->addr = 0;
  1287.         }
  1288.  
  1289.     /* write start of table */
  1290.         upd_short(current_break_address-2,
  1291.             mem_block[A_PROGRAM].current_size);
  1292.  
  1293.     add_to_mem_block(A_PROGRAM, mem_block[A_CASE_LABELS].block,
  1294.             mem_block[A_CASE_LABELS].current_size );
  1295.         /* calculate starting index for itarative search at execution time */
  1296.         for(i=0xf0,o=6; o<<1 <= mem_block[A_CASE_LABELS].current_size; )
  1297.             i++,o<<=1;
  1298.         if (block_index == A_CASE_STRINGS) i = ( i << 4 ) | 0xf;
  1299.         /* and store it */
  1300.         mem_block[A_PROGRAM].block[current_break_address-3] &= i;
  1301. #if 0  /* neither the code for ordinary switch is fully debugged now,
  1302.     * nor is the code for packed switch tables complete */
  1303.     d = ((struct case_heap_entry*)heap_start)->key;
  1304.     if ( (r-d)*sizeof(short) < heap_end_offs ) {
  1305.         mem_block[A_PROGRAM].block[current_break_address-3] &= 0xfe;
  1306.             upd_short(current_break_address-2, mem_block[A_PROGRAM].current_size);
  1307.             size_without_table = mem_block[A_PROGRAM].current_size;
  1308.         r = heap_end_offs / sizeof(struct case_heap_entry);
  1309.         add_to_mem_block(A_PROGRAM,mem_block[A_PROGRAM]->block,
  1310.         r * sizeof(short) );
  1311.         memset(mem_block[A_PROGRAM]->block+size_without_table,
  1312.         '\0',r * sizeof(short) );
  1313.         ins_long( d );
  1314.         for(; --r; heap_start += sizeof(struct case_heap_entry) )
  1315.         {
  1316.         upd_short(size_without_table + sizeof(short)*
  1317.                     ( ((struct case_heap_entry*)heap_start)->key - d )
  1318.           , ((struct case_heap_entry*)heap_start)->addr );
  1319.         }
  1320.         }
  1321. #endif /* 0 */
  1322.     upd_short(current_break_address, mem_block[A_PROGRAM].current_size);
  1323.     
  1324.     mem_block[A_CASE_NUMBERS].current_size = current_case_number_heap;
  1325.     mem_block[A_CASE_STRINGS].current_size = current_case_string_heap;
  1326.         current_break_address = pop_address();
  1327.     zero_case_label = pop_address();
  1328.         current_case_string_heap = pop_address();
  1329.         current_case_number_heap = pop_address();
  1330.         current_break_stack_need -= sizeof(short);
  1331.     } ;
  1332.  
  1333. case: F_CASE case_label ':'
  1334.     {
  1335.     struct case_heap_entry temp;
  1336.  
  1337.     if ( !( current_break_address & BREAK_FROM_CASE ) ) {
  1338.         yyerror("Case outside switch");
  1339.         break;
  1340.     }
  1341.     temp.key = $2.key;
  1342.     temp.addr = mem_block[A_PROGRAM].current_size;
  1343.     temp.line = current_line;
  1344.     add_to_case_heap($2.block,&temp);
  1345.     }
  1346.     | F_CASE case_label F_RANGE case_label ':'
  1347.     {
  1348.     struct case_heap_entry temp;
  1349.  
  1350.     if ( $2.block != A_CASE_NUMBERS || $4.block != A_CASE_NUMBERS )
  1351.         yyerror("String case labels not allowed as range bounds");
  1352.     if ($2.key > $4.key) break;
  1353.     temp.key = $2.key;
  1354.     temp.addr = 1;
  1355.     temp.line = current_line;
  1356.     add_to_case_heap(A_CASE_NUMBERS,&temp);
  1357.     temp.key = $4.key;
  1358.     temp.addr = mem_block[A_PROGRAM].current_size;
  1359.     temp.line = 0;
  1360.     add_to_case_heap(A_CASE_NUMBERS,&temp);
  1361.     } ;
  1362.     
  1363. case_label: constant
  1364.         {
  1365.         if ( !(zero_case_label & NO_STRING_CASE_LABELS) )
  1366.         yyerror("Mixed case label list not allowed");
  1367.         if ( $$.key = $1 )
  1368.             zero_case_label |= SOME_NUMERIC_CASE_LABELS;
  1369.         else
  1370.         zero_case_label |= mem_block[A_PROGRAM].current_size;
  1371.         $$.block = A_CASE_NUMBERS;
  1372.     }
  1373.       | string_constant
  1374.         {
  1375.         if ( zero_case_label & SOME_NUMERIC_CASE_LABELS )
  1376.         yyerror("Mixed case label list not allowed");
  1377.         zero_case_label &= ~NO_STRING_CASE_LABELS;
  1378.             store_prog_string($1);
  1379.             $$.key = (int)$1;
  1380.         $$.block = A_CASE_STRINGS;
  1381.         }
  1382.       ;
  1383.  
  1384. constant: const1
  1385.     | constant '|' const1 { $$ = $1 | $3; } ;
  1386.  
  1387. const1: const2
  1388.       | const1 '^' const2 { $$ = $1 ^ $3; } ;
  1389.  
  1390. const2: const3
  1391.       | const2 '&' const3 { $$ = $1 & $3; } ;
  1392.  
  1393. const3: const4
  1394.       | const3 F_EQ const4 { $$ = $1 == $3; }
  1395.       | const3 F_NE const4 { $$ = $1 != $3; } ;
  1396.  
  1397. const4: const5
  1398.       | const4 '>'  const5 { $$ = $1 >  $3; }
  1399.       | const4 F_GE const5 { $$ = $1 >= $3; }
  1400.       | const4 '<'  const5 { $$ = $1 <  $3; }
  1401.       | const4 F_LE const5 { $$ = $1 <= $3; } ;
  1402.  
  1403. const5: const6
  1404.       | const5 F_LSH const6 { $$ = $1 << $3; }
  1405.       | const5 F_RSH const6 { $$ = $1 >> $3; } ;
  1406.  
  1407. const6: const7
  1408.       | const6 '+' const7 { $$ = $1 + $3; }
  1409.       | const6 '-' const7 { $$ = $1 - $3; } ;
  1410.  
  1411. const7: const8
  1412.       | const7 '*' const8 { $$ = $1 * $3; }
  1413.       | const7 '%' const8 { $$ = $1 % $3; }
  1414.       | const7 '/' const8 { $$ = $1 / $3; } ;
  1415.  
  1416. const8: const9
  1417.       | '(' constant ')' { $$ = $2; } ;
  1418.  
  1419. const9: F_NUMBER
  1420.       | '-'   F_NUMBER { $$ = -$2; }
  1421.       | F_NOT F_NUMBER { $$ = !$2; }
  1422.       | '~'   F_NUMBER { $$ = ~$2; } ;
  1423.  
  1424. default: F_DEFAULT ':'
  1425.     {
  1426.     if ( !( current_break_address & BREAK_FROM_CASE ) ) {
  1427.         yyerror("Default outside switch");
  1428.         break;
  1429.     }
  1430.     current_break_address &= ~(BREAK_ON_STACK|BREAK_FROM_CASE);
  1431.     if ( read_short(current_break_address+2 ) )
  1432.         yyerror("Duplicate default");
  1433.     upd_short(current_break_address+2, mem_block[A_PROGRAM].current_size);
  1434.     current_break_address |= (BREAK_ON_STACK|BREAK_FROM_CASE);
  1435.     } ;
  1436.  
  1437.  
  1438. comma_expr: expr0 { $$ = $1; }
  1439.           | comma_expr { ins_f_byte(F_POP_VALUE); }
  1440.     ',' expr0
  1441.     { $$ = $4; } ;
  1442.  
  1443. expr0:  expr01
  1444.      | lvalue assign expr0
  1445.     {
  1446.         if (exact_types && !compatible_types($1, $3) &&
  1447.         !($1 == TYPE_STRING && $3 == TYPE_NUMBER && $2 == F_ADD_EQ))
  1448.         {
  1449.         type_error("Bad assignment. Rhs", $3);
  1450.         }
  1451.         ins_f_byte($2);
  1452.         $$ = $3;
  1453.     }
  1454.      | error assign expr01 { yyerror("Illegal LHS");  $$ = TYPE_ANY; };
  1455.  
  1456. expr01: expr1 { $$ = $1; }
  1457.      | expr1 '?'
  1458.     {
  1459.         ins_f_byte(F_JUMP_WHEN_ZERO);
  1460.         push_address();
  1461.         ins_short(0);
  1462.     }
  1463.       expr01
  1464.     {
  1465.         int i;
  1466.         i = pop_address();
  1467.         ins_f_byte(F_JUMP); push_address(); ins_short(0);
  1468.         upd_short(i, mem_block[A_PROGRAM].current_size);
  1469.     }
  1470.       ':' expr01
  1471.     {
  1472.         upd_short(pop_address(), mem_block[A_PROGRAM].current_size);
  1473.         if (exact_types && !compatible_types($4, $7)) {
  1474.         type_error("Different types in ?: expr", $4);
  1475.         type_error("                      and ", $7);
  1476.         }
  1477.         if ($4 == TYPE_ANY) $$ = $7;
  1478.         else if ($7 == TYPE_ANY) $$ = $4;
  1479.         else if (TYPE($4, TYPE_MOD_POINTER|TYPE_ANY)) $$ = $7;
  1480.         else if (TYPE($7, TYPE_MOD_POINTER|TYPE_ANY)) $$ = $4;
  1481.         else $$ = $4;
  1482.     };
  1483.  
  1484. assign: '=' { $$ = F_ASSIGN; }
  1485.       | F_AND_EQ { $$ = F_AND_EQ; }
  1486.       | F_OR_EQ { $$ = F_OR_EQ; }
  1487.       | F_XOR_EQ { $$ = F_XOR_EQ; }
  1488.       | F_LSH_EQ { $$ = F_LSH_EQ; }
  1489.       | F_RSH_EQ { $$ = F_RSH_EQ; }
  1490.       | F_ADD_EQ { $$ = F_ADD_EQ; }
  1491.       | F_SUB_EQ { $$ = F_SUB_EQ; }
  1492.       | F_MULT_EQ { $$ = F_MULT_EQ; }
  1493.       | F_MOD_EQ { $$ = F_MOD_EQ; }
  1494.       | F_DIV_EQ { $$ = F_DIV_EQ; };
  1495.  
  1496. return: F_RETURN
  1497.     {
  1498.         if (exact_types && !TYPE(exact_types, TYPE_VOID))
  1499.         type_error("Must return a value for a function declared",
  1500.                exact_types);
  1501.         ins_f_byte(F_CONST0);
  1502.         ins_f_byte(F_RETURN);
  1503.     }
  1504.       | F_RETURN comma_expr
  1505.     {
  1506.         if (exact_types && !TYPE($2, exact_types & TYPE_MOD_MASK))
  1507.         type_error("Return type not matching", exact_types);
  1508.         ins_f_byte(F_RETURN);
  1509.     };
  1510.  
  1511. expr_list: /* empty */        { $$ = 0; }
  1512.      | expr_list2        { $$ = $1; }
  1513.      | expr_list2 ','    { $$ = $1; } ; /* Allow a terminating comma */
  1514.  
  1515. expr_list2: expr0        { $$ = 1; add_arg_type($1); }
  1516.          | expr_list2 ',' expr0    { $$ = $1 + 1; add_arg_type($3); } ;
  1517.  
  1518. m_expr_list: /* empty */    { $$ = 0; }
  1519.      | m_expr_list2        { $$ = $1; }
  1520.      | m_expr_list2 ','    { $$ = $1; } ; /* Allow a terminating comma */
  1521.  
  1522. m_expr_list2: expr0 ':' expr1    { $$ = 2; add_arg_type($1); add_arg_type($3); }
  1523.      | m_expr_list2 ',' expr0 ':' expr1 { $$ = $1 + 2; add_arg_type($3); add_arg_type($5); }
  1524.  
  1525. expr1: expr2 { $$ = $1; }
  1526.      | expr2 F_LOR
  1527.     {
  1528.         ins_f_byte(F_DUP); ins_f_byte(F_JUMP_WHEN_NON_ZERO);
  1529.         push_address();
  1530.         ins_short(0);
  1531.         ins_f_byte(F_POP_VALUE);
  1532.     }
  1533.        expr1
  1534.     {
  1535.         upd_short(pop_address(), mem_block[A_PROGRAM].current_size);
  1536.         if ($1 == $4)
  1537.         $$ = $1;
  1538.         else
  1539.         $$ = TYPE_ANY;    /* Return type can't be known */
  1540.     };
  1541.  
  1542. expr2: expr211 { $$ = $1; }
  1543.      | expr211 F_LAND
  1544.     {
  1545.         ins_f_byte(F_DUP); ins_f_byte(F_JUMP_WHEN_ZERO);
  1546.         push_address();
  1547.         ins_short(0);
  1548.         ins_f_byte(F_POP_VALUE);
  1549.     }
  1550.        expr2
  1551.     {
  1552.         upd_short(pop_address(), mem_block[A_PROGRAM].current_size);
  1553.         if ($1 == $4)
  1554.         $$ = $1;
  1555.         else
  1556.         $$ = TYPE_ANY;    /* Return type can't be known */
  1557.     } ;
  1558.  
  1559. expr211: expr212
  1560.        | expr211 '|' expr212
  1561.           {
  1562.           if (exact_types && !TYPE($1,TYPE_NUMBER))
  1563.           type_error("Bad argument 1 to |", $1);
  1564.           if (exact_types && !TYPE($3,TYPE_NUMBER))
  1565.           type_error("Bad argument 2 to |", $3);
  1566.           $$ = TYPE_NUMBER;
  1567.           ins_f_byte(F_OR);
  1568.       };
  1569.  
  1570. expr212: expr213
  1571.        | expr212 '^' expr213
  1572.       {
  1573.           if (exact_types && !TYPE($1,TYPE_NUMBER))
  1574.           type_error("Bad argument 1 to ^", $1);
  1575.           if (exact_types && !TYPE($3,TYPE_NUMBER))
  1576.           type_error("Bad argument 2 to ^", $3);
  1577.           $$ = TYPE_NUMBER;
  1578.           ins_f_byte(F_XOR);
  1579.       };
  1580.  
  1581. expr213: expr22
  1582.        | expr213 '&' expr22
  1583.       {
  1584.           ins_f_byte(F_AND);
  1585.           if ( !TYPE($1,TYPE_MOD_POINTER) || !TYPE($3,TYPE_MOD_POINTER) ) {
  1586.               if (exact_types && !TYPE($1,TYPE_NUMBER))
  1587.               type_error("Bad argument 1 to &", $1);
  1588.               if (exact_types && !TYPE($3,TYPE_NUMBER))
  1589.               type_error("Bad argument 2 to &", $3);
  1590.           }
  1591.           $$ = TYPE_NUMBER;
  1592.       };
  1593.  
  1594. expr22: expr23
  1595.       | expr24 F_EQ expr24
  1596.     {
  1597.         int t1 = $1 & TYPE_MOD_MASK, t2 = $3 & TYPE_MOD_MASK;
  1598.         if (exact_types && t1 != t2 && t1 != TYPE_ANY && t2 != TYPE_ANY) {
  1599.         type_error("== always false because of different types", $1);
  1600.         type_error("                               compared to", $3);
  1601.         }
  1602.         ins_f_byte(F_EQ);
  1603.         $$ = TYPE_NUMBER;
  1604.     };
  1605.       | expr24 F_NE expr24
  1606.     {
  1607.         int t1 = $1 & TYPE_MOD_MASK, t2 = $3 & TYPE_MOD_MASK;
  1608.         if (exact_types && t1 != t2 && t1 != TYPE_ANY && t2 != TYPE_ANY) {
  1609.         type_error("!= always true because of different types", $1);
  1610.         type_error("                               compared to", $3);
  1611.         }
  1612.         ins_f_byte(F_NE);
  1613.         $$ = TYPE_NUMBER;
  1614.     };
  1615.  
  1616. expr23: expr24
  1617.       | expr24 '>' expr24
  1618.     { $$ = TYPE_NUMBER; ins_f_byte(F_GT); };
  1619.       | expr24 F_GE expr24
  1620.     { $$ = TYPE_NUMBER; ins_f_byte(F_GE); };
  1621.       | expr24 '<' expr24
  1622.     { $$ = TYPE_NUMBER; ins_f_byte(F_LT); };
  1623.       | expr24 F_LE expr24
  1624.     { $$ = TYPE_NUMBER; ins_f_byte(F_LE); };
  1625.  
  1626. expr24: expr25
  1627.       | expr24 F_LSH expr25
  1628.     {
  1629.         ins_f_byte(F_LSH);
  1630.         $$ = TYPE_NUMBER;
  1631.         if (exact_types && !TYPE($1, TYPE_NUMBER))
  1632.         type_error("Bad argument number 1 to '<<'", $1);
  1633.         if (exact_types && !TYPE($3, TYPE_NUMBER))
  1634.         type_error("Bad argument number 2 to '<<'", $3);
  1635.     };
  1636.       | expr24 F_RSH expr25
  1637.     {
  1638.         ins_f_byte(F_RSH);
  1639.         $$ = TYPE_NUMBER;
  1640.         if (exact_types && !TYPE($1, TYPE_NUMBER))
  1641.         type_error("Bad argument number 1 to '>>'", $1);
  1642.         if (exact_types && !TYPE($3, TYPE_NUMBER))
  1643.         type_error("Bad argument number 2 to '>>'", $3);
  1644.     };
  1645.  
  1646. expr25: expr27
  1647.       | expr25 '+' expr27    /* Type checks of this case is complicated */
  1648.     { ins_f_byte(F_ADD); $$ = TYPE_ANY; };
  1649.       | expr25 '-' expr27
  1650.     {
  1651.         int bad_arg = 0;
  1652.  
  1653.         if (exact_types) {
  1654.         if (!TYPE($1, TYPE_NUMBER) && !($1 & TYPE_MOD_POINTER) ) {
  1655.                     type_error("Bad argument number 1 to '-'", $1);
  1656.             bad_arg++;
  1657.         }
  1658.         if (!TYPE($3, TYPE_NUMBER) && !($3 & TYPE_MOD_POINTER) ) {
  1659.                     type_error("Bad argument number 2 to '-'", $3);
  1660.             bad_arg++;
  1661.         }
  1662.         }
  1663.         $$ = TYPE_ANY;
  1664.         if (($1 & TYPE_MOD_POINTER) || ($3 & TYPE_MOD_POINTER))
  1665.         $$ = TYPE_MOD_POINTER | TYPE_ANY;
  1666.         if (!($1 & TYPE_MOD_POINTER) || !($3 & TYPE_MOD_POINTER)) {
  1667.         if (exact_types && $$ != TYPE_ANY && !bad_arg)
  1668.             yyerror("Arguments to '-' don't match");
  1669.         $$ = TYPE_NUMBER;
  1670.         }
  1671.         ins_f_byte(F_SUBTRACT);
  1672.     };
  1673.  
  1674. expr27: expr28
  1675.       | expr27 '*' expr3
  1676.     {
  1677.         if (exact_types && !TYPE($1, TYPE_NUMBER))
  1678.         type_error("Bad argument number 1 to '*'", $1);
  1679.         if (exact_types && !TYPE($3, TYPE_NUMBER))
  1680.         type_error("Bad argument number 2 to '*'", $3);
  1681.         ins_f_byte(F_MULTIPLY);
  1682.         $$ = TYPE_NUMBER;
  1683.     };
  1684.       | expr27 '%' expr3
  1685.     {
  1686.         if (exact_types && !TYPE($1, TYPE_NUMBER))
  1687.         type_error("Bad argument number 1 to '%'", $1);
  1688.         if (exact_types && !TYPE($3, TYPE_NUMBER))
  1689.         type_error("Bad argument number 2 to '%'", $3);
  1690.         ins_f_byte(F_MOD);
  1691.         $$ = TYPE_NUMBER;
  1692.     };
  1693.       | expr27 '/' expr3
  1694.     {
  1695.         if (exact_types && !TYPE($1, TYPE_NUMBER))
  1696.         type_error("Bad argument number 1 to '/'", $1);
  1697.         if (exact_types && !TYPE($3, TYPE_NUMBER))
  1698.         type_error("Bad argument number 2 to '/'", $3);
  1699.         ins_f_byte(F_DIVIDE);
  1700.         $$ = TYPE_NUMBER;
  1701.     };
  1702.  
  1703. expr28: expr3
  1704.     | cast expr3
  1705.           {
  1706.           $$ = $1;
  1707.           if (exact_types && $2 != TYPE_ANY && $2 != TYPE_UNKNOWN &&
  1708.               $1 != TYPE_VOID)
  1709.               type_error("Casts are only legal for type mixed, or when unknown", $2);
  1710.           } ;
  1711.  
  1712. expr3: expr31
  1713.      | F_INC lvalue
  1714.         {
  1715.         ins_f_byte(F_INC);
  1716.         if (exact_types && !TYPE($2, TYPE_NUMBER))
  1717.         type_error("Bad argument to ++", $2);
  1718.         $$ = TYPE_NUMBER;
  1719.     };
  1720.      | F_DEC lvalue
  1721.         {
  1722.         ins_f_byte(F_DEC);
  1723.         if (exact_types && !TYPE($2, TYPE_NUMBER))
  1724.         type_error("Bad argument to --", $2);
  1725.         $$ = TYPE_NUMBER;
  1726.     };
  1727.      | F_NOT expr3
  1728.     {
  1729.         ins_f_byte(F_NOT);    /* Any type is valid here. */
  1730.         $$ = TYPE_NUMBER;
  1731.     };
  1732.      | '~' expr3
  1733.     {
  1734.         ins_f_byte(F_COMPL);
  1735.         if (exact_types && !TYPE($2, TYPE_NUMBER))
  1736.         type_error("Bad argument to ~", $2);
  1737.         $$ = TYPE_NUMBER;
  1738.     };
  1739.      | '-' expr3
  1740.     {
  1741.         ins_f_byte(F_NEGATE);
  1742.         if (exact_types && !TYPE($2, TYPE_NUMBER))
  1743.         type_error("Bad argument to unary '-'", $2);
  1744.         $$ = TYPE_NUMBER;
  1745.     };
  1746.  
  1747. expr31: expr4
  1748.       | lvalue F_INC
  1749.          {
  1750.          ins_f_byte(F_POST_INC);
  1751.          if (exact_types && !TYPE($1, TYPE_NUMBER))
  1752.          type_error("Bad argument to ++", $1);
  1753.          $$ = TYPE_NUMBER;
  1754.      };
  1755.       | lvalue F_DEC
  1756.          {
  1757.          ins_f_byte(F_POST_DEC);
  1758.          if (exact_types && !TYPE($1, TYPE_NUMBER))
  1759.          type_error("Bad argument to --", $1);
  1760.          $$ = TYPE_NUMBER;
  1761.      };
  1762.  
  1763. expr4: function_call
  1764.      | lvalue
  1765.     {
  1766.         int pos = mem_block[A_PROGRAM].current_size;
  1767.         /* Some optimization. Replace the push-lvalue with push-value */
  1768.         if (last_push_identifier == pos-2)
  1769.         mem_block[A_PROGRAM].block[last_push_identifier] =
  1770.             F_IDENTIFIER - F_OFFSET;
  1771.         else if (last_push_local == pos-2)
  1772.         mem_block[A_PROGRAM].block[last_push_local] =
  1773.             F_LOCAL_NAME - F_OFFSET;
  1774.         else if (last_push_indexed == pos-1)
  1775.         mem_block[A_PROGRAM].block[last_push_indexed] =
  1776.             F_INDEX - F_OFFSET;
  1777.         else if (last_push_indexed != 0)
  1778.         fatal("Should be a push at this point !\n");
  1779.         $$ = $1;
  1780.     }
  1781.      | string | number
  1782.      | '(' comma_expr ')' { $$ = $2; }
  1783.      | catch { $$ = TYPE_ANY; }
  1784.      | sscanf { $$ = TYPE_NUMBER; }
  1785.      | parse_command { $$ = TYPE_NUMBER; }
  1786.      | '(' '{' expr_list '}' ')'
  1787.        {
  1788.        pop_arg_stack($3);        /* We don't care about these types */
  1789.        ins_f_byte(F_AGGREGATE);
  1790.        ins_short($3);
  1791.        $$ = TYPE_MOD_POINTER | TYPE_ANY;
  1792.        }
  1793.      | '(' '[' m_expr_list ']' ')'
  1794.        {
  1795.        pop_arg_stack($3);
  1796.        ins_f_byte(F_M_AGGREGATE);
  1797.        ins_short($3);
  1798.        $$ = TYPE_MAPPING;
  1799.        };
  1800.  
  1801. catch: F_CATCH { ins_f_byte(F_CATCH); push_address(); ins_short(0);}
  1802.        '(' comma_expr ')'
  1803.            {
  1804.            ins_f_byte(F_POP_VALUE);
  1805. #if 1
  1806.            ins_f_byte(F_CONST0);
  1807.            ins_f_byte(F_THROW);
  1808. #else
  1809.            ins_f_byte(F_RETURN);
  1810. #endif
  1811.            upd_short(pop_address(),
  1812.                  mem_block[A_PROGRAM].current_size);
  1813.            };
  1814.  
  1815. sscanf: F_SSCANF '(' expr0 ',' expr0 lvalue_list ')'
  1816.     {
  1817.         ins_f_byte(F_SSCANF); ins_byte($6 + 2);
  1818.     }
  1819.  
  1820. parse_command: F_PARSE_COMMAND '(' expr0 ',' expr0 ',' expr0 lvalue_list ')'
  1821.     {
  1822.         ins_f_byte(F_PARSE_COMMAND); ins_byte($8 + 3);
  1823.     }
  1824.  
  1825. lvalue_list: /* empty */ { $$ = 0; }
  1826.        | ',' lvalue lvalue_list { $$ = 1 + $3; } ;
  1827.  
  1828. lvalue: F_IDENTIFIER
  1829.     {
  1830.         int i = verify_declared($1);
  1831.         last_push_identifier = mem_block[A_PROGRAM].current_size;
  1832.         ins_f_byte(F_PUSH_IDENTIFIER_LVALUE);
  1833.         ins_byte(i);
  1834.         xfree($1);
  1835.         if (i == -1)
  1836.         $$ = TYPE_ANY;
  1837.         else
  1838.         $$ = VARIABLE(i)->type & TYPE_MOD_MASK;
  1839.     }
  1840.         | F_LOCAL_NAME
  1841.     {
  1842.         last_push_local = mem_block[A_PROGRAM].current_size;
  1843.         ins_f_byte(F_PUSH_LOCAL_VARIABLE_LVALUE);
  1844.         ins_byte($1);
  1845.         $$ = type_of_locals[$1];
  1846.     }
  1847.     | expr4 '[' comma_expr F_RANGE comma_expr ']'
  1848.       {
  1849.           ins_f_byte(F_RANGE);
  1850.           last_push_indexed = 0;
  1851.           if (exact_types) {
  1852.           if (($1 & TYPE_MOD_POINTER) == 0 && !TYPE($1, TYPE_STRING))
  1853.               type_error("Bad type to indexed value", $1);
  1854.           if (!TYPE($3, TYPE_NUMBER))
  1855.               type_error("Bad type of index", $3);
  1856.           if (!TYPE($5, TYPE_NUMBER))
  1857.               type_error("Bad type of index", $5);
  1858.           }
  1859.           if ($1 == TYPE_ANY)
  1860.           $$ = TYPE_ANY;
  1861.           else if (TYPE($1, TYPE_STRING))
  1862.           $$ = TYPE_STRING;
  1863.           else if ($1 & TYPE_MOD_POINTER)
  1864.           $$ = $1;
  1865.           else if (exact_types)
  1866.           type_error("Bad type of argument used for range", $1);
  1867.       };
  1868.     | expr4 '[' comma_expr ']'
  1869.       {
  1870.           last_push_indexed = mem_block[A_PROGRAM].current_size;
  1871.           ins_f_byte(F_PUSH_INDEXED_LVALUE);
  1872.           if (exact_types  && !($1 & TYPE_MAPPING)) {
  1873.           if (($1 & TYPE_MOD_POINTER) == 0 && !TYPE($1, TYPE_STRING))
  1874.               type_error("Bad type to indexed value", $1);
  1875.           if (!TYPE($3, TYPE_NUMBER))
  1876.               type_error("Bad type of index", $3);
  1877.           }
  1878.           if ($1 == TYPE_ANY)
  1879.           $$ = TYPE_ANY;
  1880.           else if (TYPE($1, TYPE_STRING))
  1881.           $$ = TYPE_NUMBER;
  1882.           else if ($1 == TYPE_MAPPING)
  1883.           $$ = TYPE_ANY;
  1884.           else
  1885.           $$ = $1 & TYPE_MOD_MASK & ~TYPE_MOD_POINTER;
  1886.       };
  1887.  
  1888. string: F_STRING
  1889.     {
  1890.         ins_f_byte(F_STRING);
  1891.         ins_short(store_prog_string($1));
  1892.         xfree($1);
  1893.         $$ = TYPE_STRING;
  1894.     };
  1895.  
  1896. string_constant: string_con1
  1897.         {
  1898.             char *p = make_shared_string($1);
  1899.             xfree($1);
  1900.             $$ = p;
  1901.         };
  1902.  
  1903. string_con1: F_STRING
  1904.        | string_con1 '+' F_STRING
  1905.     {
  1906.         $$ = xalloc( strlen($1) + strlen($3) + 1 );
  1907.         strcpy($$, $1);
  1908.         strcat($$, $3);
  1909.         xfree($1);
  1910.         xfree($3);
  1911.     };
  1912.  
  1913. function_call: function_name
  1914.     {
  1915.     /* This seems to be an ordinary function call. But, if the function
  1916.      * is not defined, then it might be a call to a simul_efun.
  1917.      * If it is, then we make it a call_other(), which requires the
  1918.      * function name as argument.
  1919.      * We have to remember until after parsing the arguments if it was
  1920.      * a simulated efun or not, which means that the pointer has to be
  1921.      * pushed on a stack. Use the internal yacc stack for this purpose.
  1922.      */
  1923.     $<funp>$ = 0;
  1924.     if (defined_function($1, 0) == -1) {
  1925.         char *p = make_shared_string($1);
  1926.         $<funp>$ = find_simul_efun(p);
  1927.         if ($<funp>$ && !($<funp>$->type & TYPE_MOD_STATIC)) {
  1928.         ins_f_byte(F_STRING);
  1929.         ins_short(store_prog_string(
  1930.                   query_simul_efun_file_name()));
  1931.         ins_f_byte(F_STRING);
  1932.         ins_short(store_prog_string(p));
  1933.         } else {
  1934.         $<funp>$ = 0;
  1935.         }
  1936.         free_string(p);
  1937.     }
  1938.     }
  1939.     '(' expr_list ')'
  1940.     { 
  1941.     int f;
  1942.     int efun_override = strncmp($1, "efun::", 6) == 0;
  1943.  
  1944.     if ($<funp>2) {
  1945.         ins_f_byte(F_CALL_OTHER);
  1946.         ins_byte($4 + 2);
  1947. #ifdef CACHE_CALL_OTHER
  1948.         ins_short(-1); 
  1949. #endif
  1950.         $$ = $<funp>2->type;
  1951.     } else if (!efun_override && (f = defined_function($1, 0)) >= 0) {
  1952.         struct function *funp;
  1953.         ins_f_byte(F_CALL_FUNCTION_BY_ADDRESS); ins_short(f);
  1954.         ins_byte($4);    /* Actual number of arguments */
  1955.         funp = FUNCTION(f);
  1956.         if (funp->flags & NAME_UNDEFINED)
  1957.         find_inherited(funp);
  1958.         /*
  1959.          * Verify that the function has been defined already.
  1960.          */
  1961.         if ((funp->flags & NAME_UNDEFINED) &&
  1962.         !(funp->flags & NAME_PROTOTYPE) && exact_types)
  1963.         {
  1964.         char buff[100];
  1965.         sprintf(buff, "Function %.50s undefined", funp->name);
  1966.         yyerror(buff);
  1967.         }
  1968.         $$ = funp->type & TYPE_MOD_MASK;
  1969.         /*
  1970.          * Check number of arguments.
  1971.          */
  1972.         if (funp->num_arg != $4 && !(funp->type & TYPE_MOD_VARARGS) &&
  1973.         (funp->flags & NAME_STRICT_TYPES) && exact_types)
  1974.         {
  1975.         char buff[100];
  1976.         sprintf(buff, "Wrong number of arguments to %.60s", $1);
  1977.         yyerror(buff);
  1978.         }
  1979.         /*
  1980.          * Check the argument types.
  1981.          */
  1982.         if (exact_types && *(unsigned short *)&mem_block[A_ARGUMENT_INDEX].block[f * sizeof (unsigned short)] != INDEX_START_NONE)
  1983.         {
  1984.         int i, first;
  1985.         unsigned short *arg_types;
  1986.         
  1987.         arg_types = (unsigned short *)
  1988.             mem_block[A_ARGUMENT_TYPES].block;
  1989.         first = *(unsigned short *)&mem_block[A_ARGUMENT_INDEX].block[f * sizeof (unsigned short)];
  1990.         for (i=0; i < funp->num_arg && i < $4; i++) {
  1991.             int tmp = get_argument_type(i, $4);
  1992.             if (!TYPE(tmp, arg_types[first + i])) {
  1993.             char buff[100];
  1994.             sprintf(buff, "Bad type for argument %d %s", i+1,
  1995.                 get_two_types(arg_types[first+i], tmp));
  1996.             yyerror(buff);
  1997.             }
  1998.         }
  1999.         }
  2000.     } else if (efun_override || (f = lookup_predef($1)) != -1) {
  2001.         int min, max, def, *argp;
  2002.         extern int efun_arg_types[];
  2003.  
  2004.         if (efun_override) {
  2005.         f = lookup_predef($1+6);
  2006.         }
  2007.         if (f == -1) {    /* Only possible for efun_override */
  2008.         char buff[100];
  2009.         sprintf(buff, "Unknown efun: %s", $1+6);
  2010.         yyerror(buff);
  2011.         } else {
  2012.         min = instrs[f-F_OFFSET].min_arg;
  2013.         max = instrs[f-F_OFFSET].max_arg;
  2014.         def = instrs[f-F_OFFSET].Default;
  2015.         $$ = instrs[f-F_OFFSET].ret_type;
  2016.         argp = &efun_arg_types[instrs[f-F_OFFSET].arg_index];
  2017.         if (def && $4 == min-1) {
  2018.             ins_f_byte(def);
  2019.             max--;
  2020.             min--;
  2021.         } else if ($4 < min) {
  2022.             char bff[100];
  2023.             sprintf(bff, "Too few arguments to %s",
  2024.                 instrs[f-F_OFFSET].name);
  2025.             yyerror(bff);
  2026.         } else if ($4 > max && max != -1) {
  2027.             char bff[100];
  2028.             sprintf(bff, "Too many arguments to %s",
  2029.                 instrs[f-F_OFFSET].name);
  2030.             yyerror(bff);
  2031.         } else if (max != -1 && exact_types) {
  2032.             /*
  2033.              * Now check all types of the arguments to efuns.
  2034.              */
  2035.             int i, argn;
  2036.             char buff[100];
  2037.             for (argn=0; argn < $4; argn++) {
  2038.             int tmp = get_argument_type(argn, $4);
  2039.             for(i=0; !TYPE(argp[i], tmp) && argp[i] != 0; i++)
  2040.                 ;
  2041.             if (argp[i] == 0) {
  2042.                 sprintf(buff, "Bad argument %d type to efun %s()",
  2043.                     argn+1, instrs[f-F_OFFSET].name);
  2044.                 yyerror(buff);
  2045.             }
  2046.             while(argp[i] != 0)
  2047.                 i++;
  2048.             argp += i + 1;
  2049.             }
  2050.         }
  2051.         ins_f_byte(f);
  2052.         /* Only store number of arguments for instructions
  2053.          * that allowed a variable number.
  2054.          */
  2055.         if (max != min)
  2056.             ins_byte($4);/* Number of actual arguments */
  2057. #ifdef CACHE_CALL_OTHER
  2058.         if (f == F_CALL_OTHER)
  2059.             ins_short(-1); 
  2060. #endif
  2061.         }
  2062.     } else {
  2063.         struct function *funp;
  2064.  
  2065.         f = define_new_function($1, 0, 0, 0, NAME_UNDEFINED, 0);
  2066.         ins_f_byte(F_CALL_FUNCTION_BY_ADDRESS);
  2067.         ins_short(f);
  2068.         ins_byte($4);    /* Number of actual arguments */
  2069.         funp = FUNCTION(f);
  2070.         if (strchr($1, ':')) {
  2071.         /*
  2072.          * A function defined by inheritance. Find
  2073.          * real definition immediately.
  2074.          */
  2075.         find_inherited(funp);
  2076.         }
  2077.         /*
  2078.          * Check if this function has been defined.
  2079.          * But, don't complain yet about functions defined
  2080.          * by inheritance.
  2081.          */
  2082.         if (exact_types && (funp->flags & NAME_UNDEFINED)) {
  2083.         char buff[100];
  2084.         sprintf(buff, "Undefined function %.50s", $1);
  2085.         yyerror(buff);
  2086.         }
  2087.         if (!(funp->flags & NAME_UNDEFINED))
  2088.         $$ = funp->type & TYPE_MOD_MASK;
  2089.         else
  2090.         $$ = TYPE_ANY;    /* Just a guess */
  2091.     }
  2092.     xfree($1);
  2093.     pop_arg_stack($4);    /* Argument types not needed more */
  2094.     }
  2095. | expr4 F_ARROW function_name
  2096.     {
  2097.     ins_f_byte(F_STRING);
  2098.     ins_short(store_prog_string($3));
  2099.     xfree($3);
  2100.     }
  2101. '(' expr_list ')'
  2102.     {
  2103.     ins_f_byte(F_CALL_OTHER);
  2104.     ins_byte($6 + 2);
  2105.     $$ = TYPE_UNKNOWN;
  2106.  
  2107. #ifdef CACHE_CALL_OTHER
  2108.     ins_short(-1);
  2109. #endif
  2110.  
  2111.     pop_arg_stack($6);    /* No good need of these arguments */
  2112.     };
  2113.  
  2114. function_name: any_ident
  2115.          | F_COLON_COLON any_ident
  2116.         {
  2117.             char *p = xalloc(strlen($2) + 3);
  2118.             strcpy(p, "::"); strcat(p, $2); xfree($2);
  2119.             $$ = p;
  2120.         }
  2121.           | any_ident F_COLON_COLON any_ident
  2122.         {
  2123.             char *p = xalloc(strlen($1) + strlen($3) + 3);
  2124.             strcpy(p, $1); strcat(p, "::"); strcat(p, $3);
  2125.             xfree($1); xfree($3);
  2126.             $$ = p;
  2127.         };
  2128.  
  2129. any_ident: F_LOCAL_NAME
  2130.         {
  2131.             char *p = xalloc(strlen(local_names[$1]) + 1);
  2132.             strcpy(p, local_names[$1]);
  2133.             $$ = p;
  2134.         }
  2135.      | F_IDENTIFIER
  2136.           ;
  2137.  
  2138. cond: condStart
  2139.       statement
  2140.     {
  2141.         int i;
  2142.         i = pop_address();
  2143.         ins_f_byte(F_JUMP); push_address(); ins_short(0);
  2144.         upd_short(i, mem_block[A_PROGRAM].current_size);
  2145.     }
  2146.       optional_else_part
  2147.     { upd_short(pop_address(), mem_block[A_PROGRAM].current_size); } ;
  2148.  
  2149. condStart: F_IF '(' comma_expr ')'
  2150.     {
  2151.         ins_f_byte(F_JUMP_WHEN_ZERO);
  2152.         push_address();
  2153.         ins_short(0);
  2154.     } ;
  2155.  
  2156. optional_else_part: /* empty */
  2157.        | F_ELSE statement ;
  2158. %%
  2159.  
  2160. void yyerror(str)
  2161. char *str;
  2162. {
  2163.     extern int num_parse_error;
  2164.  
  2165.     if (num_parse_error > 5)
  2166.     return;
  2167.     (void)fprintf(stderr, "%s: %s line %d\n", current_file, str,
  2168.           current_line);
  2169.     fflush(stderr);
  2170.     smart_log(current_file, current_line, str);
  2171.     if (num_parse_error == 0)
  2172.     save_error(str, current_file, current_line);
  2173.     num_parse_error++;
  2174. }
  2175.  
  2176. static int check_declared(str)
  2177.     char *str;
  2178. {
  2179.     struct variable *vp;
  2180.     int offset;
  2181.  
  2182.     char * interned;
  2183.     extern char* findstring PROT((char*));
  2184.   
  2185.     if (interned = findstring(str)) /* Only search if amongst strings */
  2186.         for (offset=mem_block[A_VARIABLES].current_size-sizeof(struct variable);
  2187.          offset >= 0;
  2188.          offset -= sizeof (struct variable))
  2189.     {
  2190.         vp = (struct variable *)&mem_block[A_VARIABLES].block[offset];
  2191.         if (vp->flags & NAME_HIDDEN)
  2192.             continue;
  2193.         /* Pointer comparison is possible since we use unique strings */
  2194.         if (vp->name == interned)
  2195.             return offset / sizeof (struct variable);
  2196.     }
  2197.     return -1;
  2198. }
  2199.  
  2200. static int verify_declared(str)
  2201.     char *str;
  2202. {
  2203.     int r;
  2204.  
  2205.     r = check_declared(str);
  2206.     if (r < 0) {
  2207.     char buff[100];
  2208.         (void)sprintf(buff, "Variable %s not declared !", str);
  2209.         yyerror(buff);
  2210.     return -1;
  2211.     }
  2212.     return r;
  2213. }
  2214.  
  2215. void free_all_local_names()
  2216. {
  2217.     int i;
  2218.  
  2219.     for (i=0; i<current_number_of_locals; i++) {
  2220.     xfree(local_names[i]);
  2221.     local_names[i] = 0;
  2222.     }
  2223.     current_number_of_locals = 0;
  2224.     current_break_stack_need = 0;
  2225.     max_break_stack_need = 0;
  2226. }
  2227.  
  2228. void add_local_name(str, type)
  2229.     char *str;
  2230.     int type;
  2231. {
  2232.     if (current_number_of_locals == MAX_LOCAL)
  2233.     yyerror("Too many local variables");
  2234.     else {
  2235.     type_of_locals[current_number_of_locals] = type;
  2236.     local_names[current_number_of_locals++] = str;
  2237.     }
  2238. }
  2239.  
  2240. /*
  2241.  * Copy all function definitions from an inherited object. They are added
  2242.  * as undefined, so that they can be redefined by a local definition.
  2243.  * If they are not redefined, then they will be updated, so that they
  2244.  * point to the inherited definition. See epilog(). Types will be copied
  2245.  * at that moment (if available).
  2246.  *
  2247.  * A call to an inherited function will not be
  2248.  * done through this entry (because this entry can be replaced by a new
  2249.  * definition). If an function defined by inheritance is called, then one
  2250.  * special definition will be made at first call.
  2251.  */
  2252. static int copy_functions(from, type)
  2253.     struct program *from;
  2254.     int type;
  2255. {
  2256.     int i, initializer = -1;
  2257.     unsigned short tmp_short;
  2258.  
  2259.     for (i=0; i < from->num_functions; i++) {
  2260.     /* Do not call define_new_function() from here, as duplicates would
  2261.      * be removed.
  2262.      */
  2263.     struct function fun;
  2264.     int new_type, n;
  2265.  
  2266.     fun = from->functions[i];    /* Make a copy */
  2267.     /* Prepare some data to be used if this function will not be
  2268.      * redefined.
  2269.      */
  2270.     if (strchr(fun.name, ':') || fun.type & TYPE_MOD_PRIVATE)
  2271.         fun.flags |= NAME_HIDDEN;    /* Not to be used again ! */
  2272.     if (fun.type & TYPE_MOD_PRIVATE)
  2273.         fun.flags |= NAME_INHERITED;
  2274.     fun.name = make_shared_string(fun.name);    /* Incr ref count */
  2275.     fun.offset = mem_block[A_INHERITS].current_size /
  2276.         sizeof (struct inherit) - 1;
  2277.     fun.function_index_offset = i;
  2278.     if ((n = defined_function(fun.name, 0)) >= 0) {
  2279.         struct function *funp;
  2280.  
  2281.         funp = &((struct function *)mem_block[A_FUNCTIONS].block)[n];
  2282.         if (((fun.type & TYPE_MOD_NO_MASK) &&
  2283.            !(funp->flags & NAME_UNDEFINED) &&
  2284.            !(fun.type & TYPE_MOD_PRIVATE)) ||
  2285.  
  2286.             (funp->type & TYPE_MOD_NO_MASK) &&
  2287.            !(fun.type & TYPE_MOD_PRIVATE) &&
  2288.            !(funp->flags & NAME_UNDEFINED))
  2289.         {
  2290.         char *p = (char *)alloca(80 + strlen(fun.name));
  2291.         sprintf(p, "Illegal to redefine 'nomask' function \"%s\"",
  2292.             fun.name);
  2293.         yyerror(p);
  2294.         }
  2295.     }
  2296.     if (fun.type & TYPE_MOD_NO_MASK) {
  2297.         fun.flags |= NAME_INHERITED;
  2298.     } else if (!(fun.flags & NAME_HIDDEN)) {
  2299.         fun.flags |= NAME_UNDEFINED;
  2300.     }
  2301.     /*
  2302.      * public functions should not become private when inherited
  2303.      * 'private'
  2304.      */
  2305.     new_type = type;
  2306.     if (fun.type & TYPE_MOD_PUBLIC)
  2307.         new_type &= ~TYPE_MOD_PRIVATE;
  2308.     fun.type |= new_type;
  2309.     /* marion
  2310.      * this should make possible to inherit a heart beat function, and
  2311.      * thus to mask it if wanted.
  2312.      */
  2313.     if (heart_beat == -1 && fun.name[0] == 'h' &&
  2314.         strcmp(fun.name, "heart_beat") == 0)
  2315.     {
  2316.         heart_beat = mem_block[A_FUNCTIONS].current_size /
  2317.         sizeof (struct function);
  2318.     } else if (fun.name[0] == '_' && strcmp(fun.name, "__INIT") == 0) {
  2319.         initializer = i;
  2320.         fun.flags |= NAME_INHERITED;
  2321.     }
  2322.     add_to_mem_block(A_FUNCTIONS, (char *)&fun, sizeof fun);
  2323.     /*
  2324.      * Copy information about the types of the arguments, if it is
  2325.      * available.
  2326.      */
  2327.     tmp_short = INDEX_START_NONE;    /* Presume not available. */
  2328.     if (from->type_start != 0 && from->type_start[i] != INDEX_START_NONE)
  2329.     {
  2330.         int arg;
  2331.         /*
  2332.          * They are available for function number 'i'. Copy types of
  2333.          * all arguments, and remember where they started.
  2334.          */
  2335.         tmp_short = mem_block[A_ARGUMENT_TYPES].current_size /
  2336.         sizeof from->argument_types[0];
  2337.         for (arg = 0; arg < fun.num_arg; arg++) {
  2338.         add_to_mem_block(A_ARGUMENT_TYPES,
  2339.                  &from->argument_types[from->type_start[i]],
  2340.                  sizeof (unsigned short));
  2341.         }
  2342.     }
  2343.     /*
  2344.      * Save the index where they started. Every function will have an
  2345.      * index where the type info of arguments starts.
  2346.      */
  2347.     add_to_mem_block(A_ARGUMENT_INDEX, &tmp_short, sizeof tmp_short);
  2348.     }
  2349.     return initializer;
  2350. }
  2351.  
  2352. /*
  2353.  * Copy all variabel names from the object that is inherited from.
  2354.  * It is very important that they are stored in the same order with the
  2355.  * same index.
  2356.  */
  2357. static void copy_variables(from, type)
  2358.     struct program *from;
  2359.     int type;
  2360. {
  2361.     int i;
  2362.  
  2363.     for (i=0; i<from->num_variables; i++) {
  2364.     int new_type = type;
  2365.     int n = check_declared(from->variable_names[i].name);
  2366.  
  2367.     if (n != -1 && (VARIABLE(n)->type & TYPE_MOD_NO_MASK)) {
  2368.         char *p = (char *)alloca(80 +
  2369.                      strlen(from->variable_names[i].name));
  2370.         sprintf(p, "Illegal to redefine 'nomask' variable \"%s\"",
  2371.             VARIABLE(n)->name);
  2372.         yyerror(p);
  2373.     }
  2374.     /*
  2375.      * 'public' variables should not become private when inherited
  2376.      * 'private'.
  2377.      */
  2378.     if (from->variable_names[i].type & TYPE_MOD_PUBLIC)
  2379.         new_type &= ~TYPE_MOD_PRIVATE;
  2380.     define_variable(from->variable_names[i].name,
  2381.             from->variable_names[i].type | new_type,
  2382.             from->variable_names[i].type & TYPE_MOD_PRIVATE ?
  2383.                 NAME_HIDDEN : 0);
  2384.     }
  2385. }
  2386.  
  2387. /*
  2388.  * This function is called from lex.c for every new line read from the
  2389.  * "top" file (means not included files). Some new lines are missed,
  2390.  * as with #include statements, so it is compensated for.
  2391.  */
  2392. void store_line_number_info()
  2393. {
  2394.     unsigned short offset = mem_block[A_PROGRAM].current_size;
  2395.  
  2396.     while(mem_block[A_LINENUMBERS].current_size / sizeof (short) <
  2397.       current_line)
  2398.     {
  2399.     add_to_mem_block(A_LINENUMBERS, (char *)&offset, sizeof offset);
  2400.     }
  2401. }
  2402.  
  2403. static char *get_type_name(type)
  2404.     int type;
  2405. {
  2406.     static char buff[100];
  2407.     static char *type_name[] = { "unknown", "int", "string",
  2408.                      "void", "object", "mixed", "mapping" };
  2409.     int pointer = 0;
  2410.  
  2411.     buff[0] = 0;
  2412.     if (type & TYPE_MOD_STATIC)
  2413.     strcat(buff, "static ");
  2414.     if (type & TYPE_MOD_NO_MASK)
  2415.     strcat(buff, "nomask ");
  2416.     if (type & TYPE_MOD_PRIVATE)
  2417.     strcat(buff, "private ");
  2418.     if (type & TYPE_MOD_PROTECTED)
  2419.     strcat(buff, "protected ");
  2420.     if (type & TYPE_MOD_PUBLIC)
  2421.     strcat(buff, "public ");
  2422.     if (type & TYPE_MOD_VARARGS)
  2423.     strcat(buff, "varargs ");
  2424.     type &= TYPE_MOD_MASK;
  2425.     if (type & TYPE_MOD_POINTER) {
  2426.     pointer = 1;
  2427.     type &= ~TYPE_MOD_POINTER;
  2428.     }
  2429.     if (type >= sizeof type_name / sizeof type_name[0])
  2430.     fatal("Bad type\n");
  2431.     strcat(buff, type_name[type]);
  2432.     strcat(buff," ");
  2433.     if (pointer)
  2434.     strcat(buff, "* ");
  2435.     return buff;
  2436. }
  2437.  
  2438. void type_error(str, type)
  2439.     char *str;
  2440.     int type;
  2441. {
  2442.     static char buff[100];
  2443.     char *p;
  2444.     p = get_type_name(type);
  2445.     if (strlen(str) + strlen(p) + 5 >= sizeof buff) {
  2446.     yyerror(str);
  2447.     } else {
  2448.     strcpy(buff, str);
  2449.     strcat(buff, ": \"");
  2450.     strcat(buff, p);
  2451.     strcat(buff, "\"");
  2452.     yyerror(buff);
  2453.     }
  2454. }
  2455.  
  2456. /*
  2457.  * Compile an LPC file.
  2458.  */
  2459. void compile_file() {
  2460.     int yyparse();
  2461.  
  2462.     prolog();
  2463.     yyparse();
  2464.     epilog();
  2465. }
  2466.  
  2467. static char *get_two_types(type1, type2)
  2468.     int type1, type2;
  2469. {
  2470.     static char buff[100];
  2471.  
  2472.     strcpy(buff, "( ");
  2473.     strcat(buff, get_type_name(type1));
  2474.     strcat(buff, "vs ");
  2475.     strcat(buff, get_type_name(type2));
  2476.     strcat(buff, ")");
  2477.     return buff;
  2478. }
  2479.  
  2480. /*
  2481.  * The program has been compiled. Prepare a 'struct program' to be returned.
  2482.  */
  2483. void epilog() {
  2484.     int size, i;
  2485.     char *p;
  2486.     struct function *funp;
  2487.     static int current_id_number = 1;
  2488.  
  2489. #ifdef DEBUG
  2490.     if (num_parse_error == 0 && type_of_arguments.current_size != 0)
  2491.     fatal("Failed to deallocate argument type stack\n");
  2492. #endif
  2493.     /*
  2494.      * Define the __INIT function, but only if there was any code
  2495.      * to initialize.
  2496.      */
  2497.     if (first_last_initializer_end != last_initializer_end) {
  2498.     define_new_function("__INIT", 0, 0, 0, 0, 0);
  2499.     /*
  2500.      * Change the last jump after the last initializer into a
  2501.      * return(1) statement.
  2502.      */
  2503.     mem_block[A_PROGRAM].block[last_initializer_end-1] =
  2504.         F_CONST1 - F_OFFSET;
  2505.     mem_block[A_PROGRAM].block[last_initializer_end-0] =
  2506.         F_RETURN - F_OFFSET;
  2507.     }
  2508.  
  2509.     /*
  2510.      * If functions are undefined, replace them by definitions done
  2511.      * by inheritance. All explicit "name::func" are already resolved.
  2512.      */
  2513.     for (i = 0; i < mem_block[A_FUNCTIONS].current_size; i += sizeof *funp) {
  2514.     funp = (struct function *)(mem_block[A_FUNCTIONS].block + i);
  2515.     if (!(funp->flags & NAME_UNDEFINED))
  2516.         continue;
  2517.     find_inherited(funp);
  2518.     }
  2519.     if (num_parse_error > 0) {
  2520.     prog = 0;
  2521.     for (i=0; i<NUMAREAS; i++)
  2522.         xfree(mem_block[i].block);
  2523.     return;
  2524.     }
  2525.     size = align(sizeof (struct program));
  2526.     for (i=0; i<NUMPAREAS; i++)
  2527.     size += align(mem_block[i].current_size);
  2528.     p = (char *)xalloc(size);
  2529.     prog = (struct program *)p;
  2530.     *prog = NULL_program;
  2531.     prog->total_size = size;
  2532.     prog->ref = 0;
  2533.     prog->heart_beat = heart_beat;
  2534.     prog->name = string_copy(current_file);
  2535.     prog->id_number = current_id_number++;
  2536.     total_prog_block_size += prog->total_size;
  2537.     total_num_prog_blocks += 1;
  2538.  
  2539.     p += align(sizeof (struct program));
  2540.     prog->program = p;
  2541.     if (mem_block[A_PROGRAM].current_size)
  2542.     memcpy(p, mem_block[A_PROGRAM].block,
  2543.            mem_block[A_PROGRAM].current_size);
  2544.     prog->program_size = mem_block[A_PROGRAM].current_size;
  2545.  
  2546.     p += align(mem_block[A_PROGRAM].current_size);
  2547.     prog->line_numbers = (unsigned short *)p;
  2548.     if (mem_block[A_LINENUMBERS].current_size)
  2549.     memcpy(p, mem_block[A_LINENUMBERS].block,
  2550.            mem_block[A_LINENUMBERS].current_size);
  2551.  
  2552.     p += align(mem_block[A_LINENUMBERS].current_size);
  2553.     prog->functions = (struct function *)p;
  2554.     prog->num_functions = mem_block[A_FUNCTIONS].current_size /
  2555.     sizeof (struct function);
  2556.     if (mem_block[A_FUNCTIONS].current_size)
  2557.     memcpy(p, mem_block[A_FUNCTIONS].block,
  2558.            mem_block[A_FUNCTIONS].current_size);
  2559.  
  2560.     p += align(mem_block[A_FUNCTIONS].current_size);
  2561.     prog->strings = (char **)p;
  2562.     prog->num_strings = mem_block[A_STRINGS].current_size /
  2563.     sizeof (char *);
  2564.     if (mem_block[A_STRINGS].current_size)
  2565.     memcpy(p, mem_block[A_STRINGS].block,
  2566.            mem_block[A_STRINGS].current_size);
  2567.  
  2568.     p += align(mem_block[A_STRINGS].current_size);
  2569.     prog->variable_names = (struct variable *)p;
  2570.     prog->num_variables = mem_block[A_VARIABLES].current_size /
  2571.     sizeof (struct variable);
  2572.     if (mem_block[A_VARIABLES].current_size)
  2573.     memcpy(p, mem_block[A_VARIABLES].block,
  2574.            mem_block[A_VARIABLES].current_size);
  2575.  
  2576.     p += align(mem_block[A_VARIABLES].current_size);
  2577.     prog->num_inherited = mem_block[A_INHERITS].current_size /
  2578.     sizeof (struct inherit);
  2579.     if (prog->num_inherited) {
  2580.     memcpy(p, mem_block[A_INHERITS].block,
  2581.            mem_block[A_INHERITS].current_size);
  2582.     prog->inherit = (struct inherit *)p;
  2583.     } else
  2584.     prog->inherit = 0;
  2585.     
  2586.     prog->argument_types = 0;    /* For now. Will be fixed someday */
  2587.  
  2588.     prog->type_start = 0;
  2589.     for (i=0; i<NUMAREAS; i++)
  2590.         xfree((char *)mem_block[i].block);
  2591.  
  2592.     /*  marion
  2593.     Do referencing here - avoid multiple referencing when an object
  2594.     inherits more than one object and one of the inherited is already
  2595.     loaded and not the last inherited
  2596.     */
  2597.     reference_prog (prog, "epilog");
  2598.     for (i = 0; i < prog->num_inherited; i++) {
  2599.     reference_prog (prog->inherit[i].prog, "inheritance");
  2600.     }
  2601. }
  2602.  
  2603. /*
  2604.  * Initialize the environment that the compiler needs.
  2605.  */
  2606. static void prolog() {
  2607.     int i;
  2608.  
  2609.     if (type_of_arguments.block == 0) {
  2610.     type_of_arguments.max_size = 100;
  2611.     type_of_arguments.block = xalloc(type_of_arguments.max_size);
  2612.     }
  2613.     type_of_arguments.current_size = 0;
  2614.     approved_object = 0;
  2615.     last_push_indexed = -1;
  2616.     last_push_local = -1;
  2617.     last_push_identifier = -1;
  2618.     prog = 0;        /* 0 means fail to load. */
  2619.     heart_beat = -1;
  2620.     comp_stackp = 0;    /* Local temp stack used by compiler */
  2621.     current_continue_address = 0;
  2622.     current_break_address = 0;
  2623.     num_parse_error = 0;
  2624.     free_all_local_names();    /* In case of earlier error */
  2625.     /* Initialize memory blocks where the result of the compilation
  2626.      * will be stored.
  2627.      */
  2628.     for (i=0; i < NUMAREAS; i++) {
  2629.     mem_block[i].block = xalloc(START_BLOCK_SIZE);
  2630.     mem_block[i].current_size = 0;
  2631.     mem_block[i].max_size = START_BLOCK_SIZE;
  2632.     }
  2633.     add_new_init_jump();
  2634.     first_last_initializer_end = last_initializer_end;
  2635. }
  2636.  
  2637. /*
  2638.  * Add a trailing jump after the last initialization code.
  2639.  */
  2640. void add_new_init_jump() {
  2641.     /*
  2642.      * Add a new jump.
  2643.      */
  2644.     ins_f_byte(F_JUMP);
  2645.     last_initializer_end = mem_block[A_PROGRAM].current_size;
  2646.     ins_short(0);
  2647. }
  2648.